今天写的是串讲。串讲呢,就是把以前的知识串起来捡重点。javascript
再重复一下,Typescript 的本质是对静态类型的处理。在实际项目开发中,编写 Typescript 就是定义类型。css
interface UserModel { showName(name: string[] | null): object; } class User implements UserModel { name: string, constructor(name: string){ this.name = name; } } 复制代码
这是很一个很普通的类型文件的定义,关于 Typescript 定义静态类型的历史,简要普及下html
这里重点介绍下 DefinitelyTypedjava
DefinitelyTyped 的工做方式是将**类型声明文件(xxx.d.ts
)**发布到 npm 社区上(本地开发的编辑器上能够检测到)。git
说了这么多,来一段经典的 jQuery 的类型声明文件github
// types/JQuery.d.ts // 定义类型命名空间 declare namespace JQuery { type Selector = string; type TheTypeOrArray <T> = T | T[]; type htmlString = string; } // 定义接口 interface JQuery<TElement = HTMLElement> extends Iterable<TElement> { length: number; // 重载 add(select: JQuery.Selector, context: Element): this; add(select: JQuery.Selector | JQuery.TheTypeOrArray<Element> | JQuery.htmlString | JQuery): this; children(selector?: JQuery.Selector): this; css(propertyName: string): string; html(): string; empty(): this; end(): this; eq(index: number): this; } // 导出 export default JQuery; 复制代码
jQuery 的类型声明文件源码没有这么简单,这里作了下简化,以便使用。typescript
类型声明文件(*.d.ts
)中,咱们编写的就是类型定义了,可使用 type
、class
和 interface
。npm
// type.ts // 基本 type FirstName = string; // 赋值 type LastName = FirstName; // 对象 type Developer = { name: string; age: number; } // 方法 type showName = (name: string) => string; 复制代码
// class.ts // 类 class Developer2 { name: string; age: number; showName: (name: string) => string; } 复制代码
// interface.ts // 接口 interface Option { init(): void; get(str: string): object; } 复制代码
type
(或class
)使用场景是 Typescript 的基本类型不知足需求的时候,经过定义自定义类型来组合新类型;interface
是对外输出接口,对外;为 xxx.d.ts
建立变量,就是说在顶层上定义。markdown
// declare.ts declare var age: number; declare function showAge(age: number): void; declare class DeveloperClass { name: string; } declare namespace DeveloperNs { interface skills { code(): void; } } 复制代码
// { "basketball": { name: "篮球", people: 5 }, "footerball": { name: "足球" people: 11 } } 复制代码
分析上面的数据接口,可看出属性名 basketball
和 footerball
是动态的,所以编辑器
// dynamicAttributes.ts interface BallAttr { name: string; people: number; } interface Ball { [ball: string]: BallAttr } 复制代码
// typeList.ts type BallSelect = 'basketball' | 'footerball'; interface BallAttr { name: string; people: number; } type Ball2 = { [ball in BallSelect]: BallAttr } 复制代码
单纯查看一个包或想查下本身要发的包是否有重名,可到 TypeSearch 寻结果。
说到发布,一般是这两种方式。
就是与 npm 包绑定一块儿,通常存放在根目录的 types
下,使用方下载完依赖包后悔自动检测并识别类型声明文件。
用于扩展 javascript 库的类型声明文件,其安装方式和 npm 包稍有不一样 npm install @types/xxx --save-dev
。
若是你想让本身写的类型声明文件包发布到 @types 社区,可在 DefinitelyTyped 提交一个 pull request。对于 @types 社区 下的包都是从 DefinitelyTyped 自动发布出去的,这里用到工具 types-publisher。
types
├── a.d.ts
├── b.d.ts
├── xxx.d.ts
├── index.d.ts # 入口模块
└── z.d.ts
复制代码
子模块没必要定义命名空间,外部环境就获取不到(types
目录除外)。
// a.d.ts export interface AInterface { name: string; } // b.d.ts export interface BInterface { name: string; } // xxx.d.ts export interface XXXInterface { name: string; } // z.d.ts export interface ZInterface { name: string; } 复制代码
入口文件(定义命名空间和导出子模块)
// index.d.ts import * as AModule from './a'; import * as BModule from './b'; import * as XXXModule from './xxx'; import * as ZModule from './z'; declare namespace Index { export type AInterface = AModule.AInterface; export type BInterface = BModule.BInterface; export type XXXInterface = XXXModule.XXXInterface; export type ZInterface = ZModule.ZInterface; } 复制代码