背景说明:用JavaScript开发Vue3项目时,总是会有各种各样的undefined报错;某一个方法(参数封装成对象)通过多个文件引入调用,对于调用者而言,这个方法的参数是个黑盒,后续不好维护。
TypeScript是JavaScript的超集,具有类型声明及类型自动推导的功能,利用TypeScript的类型推导功能可以解决以上两大问题。
# 迁移过程
# 1. 添加配置文件
在项目根目录下添加tsconfig.json,内容如下
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
# 2. 安装typescript 、 vue-tsc (类型检测工具)
npm i typescript --save
npm i vue-tsc --save
如果用VSCode开发,则加载插件 Vue Language Features (Volar)
# 3. 将所有JavaScript文件的扩展名 .js 修改为 .ts
(可以写个脚本修改,此处项目不大,手动修改)
# 4. 将所有Vue文件中 <script>
标签中加上 lang="ts"
<script setup lang="ts"></script>
# 5. 针对报错标红的代码进行修复
- 声明变量和定义方法的形参时需声明该变量和形参的类型
let pageNum:number = 1
function geterror (msg:string) {
console.log(msg)
}
- 声明一个复杂变量时需封装一个interface来声明复杂变量的类型
interface PageInfo {
pageNum: number;
pageSize: number;
total?: number; // 问号表示可选
}
let currentPageInfo:PageInfo = { pageNum: 1, pageSize: 10 }
当一个变量可能为undefined的时候,若确定在此场景下必存在,可以用 感叹号 强制认为其可取值
若不能确定在此场景下必存在,可以用 问号 来获取其存在时的值否则为null
let pageA:number = currentPageInfo!.pageNum
let pageB:number = currentPageInfo?.pageNum
- 若想用 ObjA[key1] (key1的值为对象的某一属性)来访问一个对象的某一个属性,TypeScript会提示错误,如下
let alexInfo = { name: 'alex', age: 20 }
let key1 = 'name'
console.log(alexInfo[key1])
// 会报错 元素隐式具有 "any" 类型,因为类型为 "string" 的表达式不能用于索引类型 "{}"。
// 在类型 "{}" 上找不到具有类型为 "string" 的参数的索引签名 ts(7053)
// 声明一个interface 来定义alexInfo这个对象的索引类型为 string 即可
interface StringKeyObj {
[index: string]: any;
}
let alexInfo:StringKeyObj = { name: 'alex', age: 20 }
let key1 = 'name'
console.log(alexInfo[key1])
// 不报错