第一次用Vue3+ts,采用了eslint(aribnb),遇到了一些问题,又不想用经常性使用any,只能逼迫自己解决问题。
本文只是记录一些自己遇到的检测问题
1.使用less并导出变量到ts使用,但是ts报错找不到
报错内容:
1 | Cannot find module 'xxx.less' or its corresponding type declarations. |
解决方法:
2.setup中获取proxy,但提示可能为null
1 | const { proxy } = getCurrentInstance(); |
提示报错内容:
1 | Property 'proxy' does not exist on type 'ComponentInternalInstance | null'. |
解决方法:
1.直接强制确认,因为毫无疑问,在页面或组件中,CurrentInstance一定存在,因此可以使用!强制标记存在
但在aribnb的eslint规则下,仍然会报警告
1 | const { proxy } = getCurrentInstance()!; |
2.使用as强转
1 | import { ComponentInternalInstance } from 'vue'; |
3.如何使用ref获取dom节点
1 | <template> |
4.如果使用Element-Plus的form组件,使用resetFields或者validate方法时,提示没有该属性
报错内容:
1 | Property 'resetFields' does not exist on type 'HTMLElement' |
解决方法:
使用InstanceType<typeof ElForm>
作为范型约束
1 | <template> |
参考:
Vue.js の Composition API における this.$refs の取得方法
6.props中已经加上约束,但是在setup中使用还是在报错
报错内容:
1 | Property 'xxx' does not exist on type 'Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; slice?: string[] | undefined; ... 16 more ...; flat?: unknown[] | undefined; }> | Readonly<...>'. |
解决方法:
额外添加一个interface,名字任意,并将setup的props参数类型标记为定义类型
1 | <script lang="ts"> |
7.如何给template加上ts类型推断
解决方法:
使用vscode,并添加vetur插件>0.29.0版本,在配置中添加
1 | vetur.experimental.templateInterpolationService: true |
参考:
木子李的回答
8.在‘no-unused-expressions’的eslint规则下,经常将?.这个判断是否存在的语法糖标记为eslint错误
(实际上?这个语法糖,除了ts,js在ES2020中也支持了,所以我觉得这个判读机制该升级了)
例如:
1 | const foo = bar && bar.tea && bar.tea.cup; |
报错内容:
1 | Expected an assignment or function call and instead saw an expression. eslint(no-unused-expressions) |
解决方法:
如果是使用vue-cli创建的项目,默认会引入‘@typescript-eslint’
在eslint配置规则中,关闭’no-unused-expressions’,开启‘@typescript-eslint/no-unused-expressions’
1 | 'no-unused-expressions': 'off', |
参考:
Typescript optional chaining and ESLint no-unused-expressions
9.添加全局挂载属性,比如axios
挂载代码:
1 | //main.ts |
使用代码:
1 | setup(){ |
会发现根本没有任何提示,并且会报错
解决方法:
新建一个xxx.d.ts声明文件,并在tsconfig中引入(可以使用include,也可以使用typeRoots等,主要看自己项目配置和路径)。
1 | import { AxiosInstance } from 'axios'; |
参考:
componentPublicInstance.ts#L41-L66
p.s:因为我对axios做了二次封装,我所有的api都写在一个文件里,类似:
1 | // api.ts |
这种,有n个接口,并且随着项目变动,我目前是手动写了一个d.ts,描述了一个interface,类似
1 | // api.d.ts |
这样,但是每新增一个接口,或者变动,我就要手动添加声明。请问有没有什么办法能把我解放出来TAT。
因为依赖了比较多的东西,我使用tsc命令单独为这个文件生成d.ts的时候会报错,无法生成。
求个答案,大佬们都是怎么做的。