背景
为了跟上前端技术的潮流,我在新项目中使用了 TypeScript 。刚开始开发的时候,遇到了一些令我一头雾水的 bug,现在整理出来,让大家和我一起避免重复踩雷。
遇到的问题
1. 在 ts 中引入 .vue 文件会报错
Cannot find module '@/components/loading-bar'.
由于 TypeScript
默认并不支持 *.vue
后缀的文件,所以在 vue
项目中引入的时候需要创建一个 vue-shim.d.ts
文件,放在项目项目对应使用目录下,例如 src/vue-shim.d.ts
// 如果使用 vue-cli3 的话,这个文件应该会被自动创建
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
意思是告诉 TypeScript
以 *.vue
为后缀的文件可以交给 vue
模块来处理。
而在代码中导入 *.vue
文件的时候,需要写上 .vue
后缀。原因还是因为 TypeScript
默认只识别 *.ts
文件,不识别 *.vue
文件。
解决办法: 引入的时候加上 .vue 后缀
2. 在 ts 中使用 webpack 中配置的 alias
会报错
解决办法:在 tsconfig.json
中进行配置:
"compilerOptions": {
// ...
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@views/*": ["src/views/*"]
}
},
3. 在 ts 中引入外部模块有时会报错,例如
import JsCookie from 'js-cookie';
部分 npm 包没有 index.d.ts
文件,因此直接 import 可能出错。
解决办法:
- 可以使用
require
例如在文件中引入
const moment = require('moment');
- 或者直接install它的ts库例如
npm i --save-dev @types/moment
4. vuex 与 typescript 支持度很差,直接使用 mapState
不起作用
解决办法:使用 vuex-class
包进行替代。
import { State } from 'vuex-class';
//...
@State myState!: string
5. 使用 element-ui 之后,this.$message
会报错
Property '$message' does not exist on type 'App'.
编译时默认拉取
node_modules/@types
下面的文件,额外还有typeRoots
和types
两个属性可以自定义配置 看下我们项目中的tsconfig文件:
{
"compilerOptions": {
"types": [
"webpack-env",
"jest"
]
}
}
设置了 types
属性,表示只使用以下位置的配置:
node_modules/@types/webpack-env
node_modules/@types/chai
但是 element-ui
的types位置在 node_modules/elememt-ui/types
下面,所以将这个位置加入了配置中:
{
"compilerOptions": {
"types": [
"webpack-env",
"jest",
"./../element-ui/types"
]
}
}
即可编译成功!