Vue JavaScript TypeScript

Vue3 项目 从 JavaScript 迁移到 TypeScript

JS开发一时爽,TS重构火葬场

Hannah
2021-10-12
3 min

背景说明:用JavaScript开发Vue3项目时,总是会有各种各样的undefined报错;某一个方法(参数封装成对象)通过多个文件引入调用,对于调用者而言,这个方法的参数是个黑盒,后续不好维护。

TypeScript是JavaScript的超集,具有类型声明及类型自动推导的功能,利用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]) 
// 不报错
Last Updated: 11/19/2021, 5:57:46 PM