declare前缀的作用
declare定义的类型只会用于编译时的检查,编译结果中会被删除。即不会生成实际代码。- 如下案例编译结果是:
var directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
declare enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
- 常量最终会被替换成原始值
- 编译的结果是:
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];
declare const enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
变量的声明
声明在全局文件或模块文件中的可见性不同
// declare var, let, const 声明变量
declare var jQuery: (selector: string) => any;
// declare function 声明方法法
declare function Fn(selector: string): any;
// declare class 声明类
declare class Animal {}
// declare enum 声明枚举类型
declare enum Directions {
Up,
Down,
}
// declare namespace 声明(含有子属性的)对象
// 模块文件后 namespace已经比较少用, 除非是给第三方包写声明文件
declare namespace NS {
function ajax(url: string, settings?: any): void;
}
// interface 和 type 声明类型
interface Animal {
}
type NumberString = number | string;
语法的声明合并
- 函数与"函数、命名空间"可以合并
- "interface"与"接口,类,函数,命名空间"可以合并
- “class"同"interface"
- 合并的属性的类型必须是唯一的
- 假如
jQuery既是一个函数,可以直接被调用jQuery('#foo'),又是一个对象.
模块声明文件
- 需要
export来导出变量,使其外部可见。 - 并且需要根据不同的模块加载器,编写不同的导出语法。
- ES6模块加载
// export 导出变量 export const name: string; // export namespace 导出(含有子属性的)对象 export namespace foo { const name: string; } // export default ES6 默认导出 export default function foo(): string; - commonjs 导出模块
// 使用 export = 之后,就不能使用ES6语法再单个导出 export { bar } export = foo; declare function foo(): string; declare namespace foo { const bar: number; } export as namespaceUMD 库声明全局变量// 一般使用 export as namespace 时,都是先有了 npm 包的声明文件,再基于它添加一条 export as namespace 语句 export as namespace foo; export = foo; declare function foo(): string; declare namespace foo { const bar: number; }
- ES6模块加载
模块扩展
-
模块扩展全局变量
// `declare global {}`是运用在模块声明文件中的,表示对原始的全局类型的增强,随模块的引入引入,随模块的卸载而卸载。 declare global { interface String { prependHello(): string; } } -
模块扩展模块(模块插件)
// 扩展原有模块的类型的声明模版 import * as moment from 'moment'; declare module 'moment' { export function foo(): moment.CalendarKey; }
三斜杠指令语法
- 全局声明文件中使用模块的类型,但是不能使用import等语法。
/// <reference types="jquery" /> declare function foo(options: JQuery.AjaxSettings): string; - 全局变量的声明文件太大时,可以通过拆分为多个文件,然后在一个入口文件中将它们一一引入,来提高代码的可维护性。比如
jQuery的声明文件就是这样的:/// <reference types="sizzle" /> /// <reference path="JQueryStatic.d.ts" /> /// <reference path="JQuery.d.ts" /> /// <reference path="misc.d.ts" /> /// <reference path="legacy.d.ts" /> export = jQuery; // namespace jQuery·