尽管TypeScript声称自己是JavaScript的超集,只是如果单纯把TypeScript作为包含类型限定的JavaScript来使用,我们会在使用过程中遇到一些可能难以理解的报错,今天我来整理一下我在使用TypeScript中遇到的问题以及解决方案。
1. 第三方依赖导入报错
有很多时候我们需要在项目中使用一些npm库,目前一些流行的npm库都有自带的类型定义文件,但是如果是早期的第三方依赖或者是个人开发不是特别流行的npm库,可能并不会有对应的类型定义,针对于一些早期的npm库,开发者可能会推出对应的@types补充包,例如我们可以使用 npm install @types/node
来进行类型补充,这样就可以避免typescript类型检查报错。如果对于一些并不流行的第三方依赖,没有对应的@types/库名,那么我们需要在typings.d.ts文件中进行类型声明:
// typings.d.ts declare module '库名' { // 在这里添加模块的类型声明 }
如果上述方法不能解决问题,那么只能使用最终的必杀技:any大法
import * as 库名 from '库名'; const instance: any = new 库名();
作为一个伤敌一千,自损八百的招数,any可以解决90%的类型保存,但是这样也就失去了ts的类型检查,作为实在没有办法在使用的解决方案。
2. 函数入参类型不匹配
有时候在我们调用方法时,typescript类型检查会提示出入参类型不匹配,这时候有两种常见的策略来解决这个问题,第一种方法可以使用强制类型转化
(arrayList as Array).slice(2,5) (changeStudentsToArray(students as Students) as Array).sort((a,b)=> a.age - b.age)
第二种方法可以使用类型继承或者类型扩展
type RealType = { [key: string]: unknown } & NeedType //或者使用接口 interface RealType extends NeedType { [key: symbol]: unknown }
3. 在单例模式中为单例添加属性
例如说在项目中写了一个带样式的控制台输出,并且在生产环境下自动屏蔽log级别的日志,我想要把这个log方法挂载到window对象上
window.log=Log //类型“Window & typeof globalThis”上不存在属性“log”。
此时,可以使用全局的类型定义
declare global { interface Window { log: (...args: any[]) => void; } } Window.prototype.log = function (...args: any[]): void { console.log(...args); };
这样,就可以直接在项目中使用log方法了。
ok,以上是今天总结的一些typescript报错,和修复方法,后续遇到了新的报错,会及时在文章里更新。