变量声明空间和类型声明空间
类型声明空间包含用来当做类型注解的内容,但不能作为变量使用。
变量声明空间包含可用作变量的内容,不能作为类型注解。
编译成JS后,会将类型声明空间完全移除。
模块
早期ES6还没出的时候,有 AMD , CommonJs。现在按ES6的标准,统一用 import export 就行。不需要过多考虑别的模块形式。
声明文件
TS中专门用来声明类型的文件,以 d.ts 结尾。
script形式引入的声明文件
例如 jQuery ,引入后会挂载到全局下一个$(jQuery)对象。为了防止命名冲突,我们要利用 declare namespace。因为限定了所有的类型声明都在jQuery下,所以使用的时候也要 jQuery.xxx 的形式。
declare namespace jQuery {interface AjaxSettings {method?: 'GET' | 'POST'data?: any;}function ajax(url: string, settings?: AjaxSettings): void;}
NPM包的声明文件
npm的三方包如果配备了声明文件,一般会与npm包绑定在一起,查看 package.json 的 types 字段。如果没有绑定,尝试安装 yarn add type/npmpackage -D ,使用者通常会自己写声明文件,发布到 @types 下。
如果以上都没有。自己可以在项目目录里定义一个 types 文件夹,专门存放声明文件。
/path/to/project├── src| └── index.ts├── types| └── foo| └── index.d.ts└── tsconfig.json
这里也要配置下tsconfig的 paths 字段,告诉ts需要解析哪里的。
"compilerOptions": {"paths": {"*": ["types/*"]}}
扩展全局变量
利用声明合并。没有使用 import export 就是全局声明。
interface String {xxx: number}
利用 declare namespace给已有的命名空间添加
declare namespace JQuery {interface CustomOptions {bar: string;}}
扩展npm包的全局变量
写一个自己的声明文件时,可能会用到其他npm包的声明文件,所以我们需要导入 import React from 'react ,导入后,则认为这个声明文件是个模块,再声明的话,都是局部类型声明,此时需要全局声明类型的话,用 declare global 。
import React from 'react'declare global {reactEle: React.Element}
这里我们就可以使用全局的 reactEle 了。
扩充原模块类型
比如 axios 导出的实例,想在它身上挂载 token 以便请求接口时使用。原本实例是不存在 token 属性的。所以:
// 导入原模块的类型import axios, { AxiosInstance } from 'axios';// 拓展它。使用interface达到类型合并的效果declare module 'axios' {interface AxiosInstance {token: any;userId: any;}}
// 使用拓展过的实例import axios from 'axios';let instance = axios.create({})instance.token = 'xxx'instance.userId = 'xxx'
声明文件的依赖
除了 import 来导入其他模块的类型之外,还有 三斜线 指令,使用场景是需要一个全局的类型,你不能使用 import 和 export 关键字,TS会认为是局部声明,需要你导入后才能使用了。
// 引入jquery。这里用的是types=xxx,表示依赖/// <reference types="jquery" />// 这里依旧暴露的还是全局类型foo,可以使用使用,不用在使用地 import 它。declare function foo(options: JQuery.AjaxSettings): string;
// node_modules/@types/jquery/index.d.ts// sizzle是跟jquery平级的库,是一种依赖/// <reference types="sizzle" />// 这里开始用的是path,表示引入文件,并不是依赖/// <reference path="JQueryStatic.d.ts" />/// <reference path="JQuery.d.ts" />/// <reference path="misc.d.ts" />/// <reference path="legacy.d.ts" />export = jQuery;
