声明文件概述
-
什么是声明文件?以 .d.ts 结尾的文件;
-
声明文件有什么作用?为 JS 代码提供类型声明;
-
声明文件的位置:
- 第一种情况:放置到 tsconfig.json 配置中 include 的目录中;
- 第二种情况:放置到 node_modules/@types 文件夹中;
- 第三种情况:手动配置配置文件 typeRoots: [];
- 第四种情况:与 JS 代码所在目录相同,并且文件名也相同的文件,后缀为 .d.ts;
第三方声明文件
-
社区已经帮我们定义好了很多的声明文件 (可以在这个页面搜索你需要的声明文件),可以直接下载下来使用,但是更推荐的是使用 @types 统一管理第三方库的声明文件;
-
@types 的使用方式很简单,直接用 npm 安装对应的声明模块即可,以 jQuery 举例:
npm install @types/jquery --save-dev
自动生成
-
如果库的源码本身就是由 ts 写的,那么在使用 tsc 脚本将 ts 编译为 js 的时候,添加 declaration: true 选项,就可以同时也生成 .d.ts 声明文件了;
{ "compilerOptions": { "module": "commonjs", "outDir": "lib", // 输出文件夹 "declaration": true, // 生成 .d.ts 文件 } }
-
上例添加了 outDir 选项,将 ts 文件的编译结果输出到 lib 目录下,然后添加了 declaration: true 选项,表示将会由 ts 文件自动生成 .d.ts 声明文件,也会输出到 lib 目录下;
书写声明文件
在日常的开发中,绝大多数时候是不需要我们单独去编写一个 TS 声明文件的,如果项目本身是用 TS 开发的,在编译的时候让 TS 自动生成声明文件,并在发布的时候将 .d.ts 文件一起发布即可;
总结了以下三种情况,需要手动定义声明文件:
- 通过 script 标签引入的第三方库;
- 使用的第三方 npm 包,但是没有提供声明文件(有 npm i @type/xxx 下载依赖、源代码中提供 .d.ts 这两种方式提供声明文件);
- 自身团队内比较优秀的 JS 库或插件,为了提升开发体验;
全局变量声明
-
使用全局变量的声明文件时,如果是以 npm install @types/xxx --save-dev 安装的,则不需要任何配置。如果是将声明文件直接存放于当前项目中,则建议和其他源码一起放到 src 目录下 (或者对应的源码目录下):
-
关键字 declare 表示声明的意思,可以用它来做出各种声明:
- declare let/const 声明全局变量;
- declare function 声明全局方法;
- declare class 声明全局类;
- declare enum 声明全局枚举类型;
- declare namespace 声明含有 (子属性) 全局对象;
- interface/type 声明全局类型;
// 变量 declare let userName: string; declare const wx: any; // 函数、函数重载 declare function getName(uid: number): string; declare function getName(): string; declare function getName(cb: () => any): any; // 类 declare class Course { cid: number; constructor(cid: number); getCoursePrice(): number; } // 枚举 declare enum Status { Loading, Success, Failed, } // 接口 interface declare 可以不需要 interface CourseInfo { cid: number; name: string; } interface CGIData<T> { data: T; retcode: 0; } // 命名空间 declare namespace Test { // 局部 Test.User interface User { name: string; age: number; } function getUserInfo(name: string): User; namespace fn { function extend(obj: any): any; } } // 可以对模块进行声明、扩展 declare module "dayjs" { function add(param: number, type: 'day' | 'week' | 'month'): string }
-
namespace: 表示命名空间,可以将其认为是一个对象,命名空间中的内容,必须通过
命名空间.成员名
访问;
为 npm 包声明
-
对于没有提供声明文件的 npm 包,可以创建一个 types 目录,来管理自己写的声明文件,同时需要在配置文件 tsconfig.json 中的 paths 和 basrUrl 中配置:
{ "compilerOptions": { "module": "commonjs", "baseUrl": "./", // types文件夹的相对路径 "paths": { "*": [ "types/*" ] } } }
-
npm 包的声明文件主要有以下几种语法:
- export 导出变量;
- export namespace:导出(含有子属性的)对象;
- export default:ES6 默认导出;
- export =:commonjs 导出模块;
TypeScriptTypeScript// types/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; }
// types/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 Options { data: any; } // 也可以使用 declare 先声明多个变量,最后再用 export 一次性导出 export { name, getName, Animal, Directions, Options };
拓展原有模块/全局变量
-
对于已经有声明定义的模块或者全局变量,可以利用 TS 中的声明合并对其进行拓展,比如在 window 下挂载的一些全局变量:
interface Window { readonly request?: any; readonly devToolsExtension?: any; readonly wx?: any; }
-
对已有模块进行拓展:
declare module "querystring" { function escape(str: string): string; function unescape(str: string): string; }
-
还可以使用三斜线的方式对声明文件进行引用:
/// <reference path=”custom.d.ts" />
TypeScript👉 类型演算
上一篇