什么是声明文件
通过创建一个名称为xxx.d.ts文件来生成一个声明文件,在声明文件中只能定义类型,不能写具体的实现逻辑。
声明文件通常是给IDE使用的,IDE通过声明文件为开发者提供类型的智能提示,提升开发的体验和效率。
d.ts文件和.ts文件的区别
.ts文件中既可以定义逻辑,也可以定义类型;而.d.ts只能定义类型。既然.ts的能力完全覆盖逻辑和类型,那.d.ts存在的意义是什么?通过举例几个实际场景来描述.d.ts文件的意义。
1. 使用通过js书写的第三方包的时候,是没有类型提示的。可以通过定义该包的.d.ts文件来为该包定义类型。
2. 通过ts书写的第三包,最终会打包出js文件和.d.ts文件产物,其中.js文件对外提供逻辑层面的能力,.d.ts文件对外提供类型提示的能力。
3. 当我们引用了全局类型上不存在的属性时,通过在.d.ts文件中拓展全局类型来规避ts报错。例如运行时在window变量上定义了customKey属性,如果不对window类型进行拓展,那么ts就会报错。我们通过在.d.ts文件中扩展window类型后,ts报错就消失了。
使用场景
1. 定义第三方npm包的类型文件。
2. 扩展全局类型。
全局类型
全局类型:区别于模块化类型,全局类型是在项目全局生效的类型,无需引入即可使用。
// 在项目下新建xxx.d.ts
declare type globalValue = number; // const v: globalValue = 1
declare function getName(name: string): string; // getName('jack')
declare interface globalConfig {
name: string
age: number
} // const config: globalConfig = { name: 'jack', age: 12 }
模块化类型
模块化类型:对类型进行模块化,避免污染全局类型。
// m.d.ts
declare const name: string
declare function getName(): string
declare namespace person { name: string }
export { name, getName, person }
// m.js
const name = 'jack'
function getName() { return name }
const person = { name: 'jack' }
export { name, getName, person }
// 引用
import config from './m.js'
console.log(config.name);
config.getName();
console.log(config.person.name);
// 模块化类型扩展全局类型
declare global {
const customValue: string
}
扩展第三包的类型文件
import "react"; // 引入需要修改的包
declare module "react" {
type newType = { // 扩展的新类型
key: number,
label: string
}
interface Component { // 合并已有的类型
newKey: string
}
}