类型声明文件:用来为已存在的 JS 库提供类型信息

TS 中的两种文件类型

  1. .ts文件
  • 既包含类型信息有可执行代码
  • 可以被编译为.js文件,然后执行
  • 用途是编写程序代码的地方
  1. .d.ts文件
  • 只包含类型信息的类型声明文件
  • 不会生成.js文件,仅用于提供类型信息
  • 用途是为 JS 提供类型信息

.ts 是 implementation(代码实现文件);.d.ts 是 declaration(类型声明文件)。

如果要为 JS 库提供类型信息,要使用 .d.ts 文件。

类型声明文件的使用

使用已有的类型声明文件

  1. 内置类型声明文件:TS 为 JS 运行时可用的所有标准化内置 API 都提供了声明文件。

比如,在使用数组时,数组所有方法都会有相应的代码提示以及类型信息:

image.png

查看 forEach 方法的类型声明,在 VSCode 中会自动跳转到 lib.es5.d.ts 类型声明文件中。 像 window、document 等 BOM、DOM API 也都有相应的类型声明(lib.dom.d.ts)。

  1. 第三方库的类型声明文件:目前,几乎所有常用的第三方库都有相应的类型声明文件。
  • 库自带类型声明文件

image.png

这种情况下,正常导入该库,TS 就会自动加载库自己的类型声明文件,以提供该库的类型声明。

  • 由 DefinitelyTyped 提供

DefinitelyTyped 是一个 github 仓库,用来提供高质量 TypeScript 类型声明。

image.png

创建自己的类型声明文件

项目内共享类型

如果多个 .ts 文件中都用到同一个类型,此时可以创建 .d.ts 文件提供该类型,实现类型共享。

  1. 创建 index.d.ts 类型声明文件。
  2. 创建需要共享的类型,并使用 export 导出(TS 中的类型也可以使用 import/export 实现模块化功能)。
  3. 在需要使用共享类型的 .ts 文件中,通过 import 导入即可(.d.ts 后缀导入时,直接省略)。
1
2
3
4
5
6
7
8
9
10
// index.d.ts
type Props = { x: number; y: number }
export { Props }

// demo.ts
import { Props } from './index'
let p1: Props = { x: 1, y: 2 }
// 同名情况
import { Point } from './demo.d';
let p2: Point = { x: 1, y: 2 }

为已有 JS 文件提供类型声明

在将 JS 项目迁移到 TS 项目时,为了让已有的 .js 文件有类型声明。或者成为库作者,创建库给其他人使用。

declare 关键字:用于类型声明,为其他地方(比如,.js 文件)已存在的变量声明类型,而不是创建一个新的变量。

  1. 对于 type、interface 等这些明确就是 TS 类型的(只能在 TS 中使用的),可以省略 declare 关键字。
  2. 对于 let、function 等具有双重含义(在 JS、TS 中都能用),应该使用 declare 关键字,明确指定此处用于类型声明。

utils.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let count = 10
let songName = '大鱼'
let position = {
x: 0,
y: 0
}
function add(x, y) {
return x + y
}
function changeDirection(direction) {
console.log(direction)
}
const fomartPoint = point => {
console.log('当前坐标:', point)
}
module.exports = { count, songName, position, add, changeDirection, fomartPoint }

utils.d.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 为 utils.js 文件来提供类型声明
declare let count: number
declare let songName: string
interface Point {
x: number
y: number
}
declare let position: Point

declare function add(x: number, y: number): number
declare function changeDirection(
direction: 'up' | 'down' | 'left' | 'right'
): void

type FomartPoint = (point: Point) => void
declare const fomartPoint: FomartPoint

// 注意:类型提供好以后,需要使用 模块化方案 中提供的
// 模块化语法,来导出声明好的类型。然后,才能在
// 其他的 .ts 文件中使用
export { count, songName, position, add, changeDirection, fomartPoint, Point }

.ts 文件在导入 .js 文件时,会自动加载与 .js 同名的 .d.ts 文件,以提供类型声明。

demo.ts

1
2
3
4
5
6
7
8
9
10
import { count, songName, add, Point } from './utils'

let p1: Point = {
x: 10,
y: 20
}
// 使用js方法变量
console.log('count', count); // count 10
console.log('songName', songName); // songName 大鱼
console.log('add()', add(1, 4)); // add() 5