ts类型声明文件的正确使用姿势

ts声明文件类型

1. DefinitelyTyped社区已定义

1
npm install @types/jquery --save-dev

2. 与npm一同发布

​ 解释: package.json 中有 types 字段,或者有一个 index.d.ts 声明文件

3. 自给自足型

创建一个 node_modules/@types/foo/index.d.ts 文件,存放 foo 模块的声明文件。不太建议用这种方案,一般只用作临时测试。
创建一个 types 目录,专门用来管理自己写的声明文件,将 foo 的声明文件放到 types/foo/index.d.ts 中。这种方式需要配置下 tsconfig.json 中的 paths 和 baseUrl 字段。

1
2
3
4
5
6
7
/path/to/project
├── src
| └── index.ts
├── types
| └── foo
| └── index.d.ts
└── tsconfig.json
1
2
3
4
5
6
7
8
9
{
"compilerOptions": {
"module": "commonjs",
"baseUrl": "./",
"paths": {
"*": ["types/*"]
}
}
}

ts声明文件书写姿势

1. 全局型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# let 
declare let jQuery: (selector: string) => any;

# function
declare function jQuery(selector: string): any;

#class
declare class Animal {
name: string;
constructor(name: string);
sayHi(): string;
}

#enum
declare enum Directions {
Up,
Down,
Left,
Right
}

#namespace
declare namespace jQuery {
function ajax(url: string, settings?: any): void;
namespace fn {
function extend(object: any): void;
}
}

2. npm包型 - export

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// types/foo/index.d.ts
export const name: string;
export function getName(): string;
export class Animal {
constructor(name: string);
sayHi(): string;
}
export enum Directions {
Up,
Down,
Left,
Right
}
export interface Options {
data: any;
}
export namespace foo {
const name: string;
namespace bar {
function baz(): string;
}
}

3. npm包型 - export default

1
2
3
4
5
6
7
8
9
10
11
12
// types/foo/index.d.ts
# functionclassinterface 可以直接默认导出,其他的变量需要先定义出来,再默认导出
export default function foo(): string;

export default Directions;
declare enum Directions {
Up,
Down,
Left,
Right
}

4. npm包型 - 先声明,在export

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// types/foo/index.d.ts
declare const name: string;
declare function getName(): string;
declare class Animal {
constructor(name: string);
sayHi(): string;
}
declare enum Directions {
Up,
Down,
Left,
Right
}
#interface 前是不需要 declare
interface Options {
data: any;
}

export { name, getName, Animal, Directions, Options };

5. module 拓展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// types/foo-bar.d.ts

declare module 'foo' {
export interface Foo {
foo: string;
}
}

declare module 'bar' {
export function bar(): string;
}

// src/index.ts

import { Foo } from 'foo';
import * as bar from 'bar';

let f: Foo;
bar.bar();

6. 三斜线指令

  • 书写一个全局变量的声明文件
  • 依赖一个全局变量的声明文件
1
2
3
4
5
// types/jquery-plugin/index.d.ts

/// <reference types="jquery" />

declare function foo(options: JQuery.AjaxSettings): string;

7. ts文件tsc自动生成声明文件

  • 命令行参数
1
--declaration(简写 -d)

8. ts发布

  • 发布到社区

@types 是统一由 DefinitelyTyped 管理的。要将声明文件发布到 @types 下,就需要给 DefinitelyTyped 创建一个 pull-request,其中包含了类型声明文件,测试代码,以及 tsconfig.json 等。

  • 与源码一起(依次查找*.d.ts)

    1. 给 package.json 中的 types 或 typings 字段指定一个类型声明文件地址

    2. 在项目根目录下,编写一个 index.d.ts 文件

    3. 针对入口文件(package.json 中的 main 字段指定的入口文件),编写一个同名不同后缀的 .d.ts 文件