TypeScript 声明自定义类型模块
目录
项目有时候修改了内置对象的原型,使它额外地拥有了一些方法,对应地要显式声明这些方法的类型,否则 TypeScript 只会用标准的 lib 去做类型检查。
下面是一个例子,让 String 增加额外的方法,同时让 TypeScript 识别到他们。
扩展 String.sayYes
下方的代码给 String 的原型增加一个 sayYes
的方法,sayYes()
会让 String 对象同意自己的表达。
String.prototype.sayYes = function () {
console.log(`${this}, YES`)
}
调用这个方法:
'AMD'.sayYes('YES')
// AMD, YES
new String('AMD').sayYes()
// AMD, YES
现在 String 已经有 sayYes
功能了,但是 TypeScript 不认,因为 TypeScript 是依据标准库做类型检查的。
显式声明 String.sayYes
既然 TypeScript 不认这个 sayYes,那就给 String 编写额外声明 ,表明 sayYes 的存在。
TypeScript 配置文件选项 typeRoots
可以指定自定义声明。
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"typeRoots": ["./typings.d.ts"]
}
}
// typings.d.ts
declare interface String {
sayYes(): void
}
声明文件以 d.ts
结尾,现在 TypeScript 不会再报错了。
引用其他声明
声明文件不支持 import,如果要引用其他声明文件,则可以用 reference 命令字。
三斜杠
///
会被编译器识别为指令 (TypeScript 三斜杠指令文档)
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"typeRoots": ["./typings.d.ts"]
}
}
// typings.d.ts
/// <reference path="./typings_string.d.ts" />
// typings_string.d.ts
declare interface String {
sayYes(): void
}
声明自定义模块
.d.ts
不仅可以声明类型,方法,还可以声明模块。
下方的 void_module
声明了一个不存在的模块,如果尝试 import、require 会导致 MODULE_NOT_FOUND
报错。但是 TypeScript 不会产生类型检查错误。
declare module 'void_module' {
function voidAction();
}
// main.ts
// 类型检查通过,但是运行会报错
import { voidAction } from 'void_module';
voidAction();
附录
按指引配置了微信小程序类型库后,不需要 import 模块也有自动提示了。typeRoots
只是一种自定义声明的方式,TypeScript 还会寻找 node_modules/@types
中所有的包,解析出里面的显式声明。所以当 TypeScript 找不到一些包的类型时,会问问是否安装了 @types/XXXX
。