# declare关键字
在 TS 的配置中,declare关键字经常出现。那么declare声明和与普通声明有什么区别呢?
通过 declare 声明的类型或者变量或者模块,在 include 包含的文件范围内,都可以直接引用而不用去import或者import type相应的变量或者类型。
也就是说,declare 告诉 TS 编译器,你担保这些变量和模块的存在,并声明了响应的类型,编译的时候不需要提示错误。
笔记
.d.ts
文件顶级声明 declare 最好不要跟 export 同级使用,不然在其他 ts 引用这个 .d.ts 的内容的时候,就需要手动 import 导入了。- 在
.d.ts
文件里如果顶级声明不用 export 的话,declare和直接写 type、interface 效果是一样的,在其他地方都可以直接引用。
// *.d.ts
declare type Ass={
a:string
}
type Bss={
b:string
}
// 可以直接使用 Ass 和 Bss 作为类型
2
3
4
5
6
7
8
9
# 一、声明指南
# 1.声明对象或属性
有一个 myLib 对象,其有一个 greet 函数和 numberOfGreetings 属性。
let greeting = myLib.greet("hello, cc!")
let count = myLib.numberOfGreetings
2
可以使用声明该对象
declare namespace myLib {
function greeting(str:string):string
let numberOfGreetings:number
}
2
3
4
# 2.重载函数
使函数支持不同的参数和返回不同的值。
declare function printName(name: string): number;
declare function printName(name: string[]): number;
let x = printName("cc"); // 合法
let y = printName(["cc", "yy"]); // 合法
let x = printName(123); // 报错:没有与此调用匹配的重载...
2
3
4
5
6
# 3.全局变量
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明全局对象(含有子属性)
interface 和 type 声明全局类型
2
3
4
5
6
# 4.声明模块
// 最经典的声明模块应该是这样了:
declare module '*.css'
declare module '*.less'
declare module '*.png'
2
3
4
在编辑ts文件的时候,如果你想导入一个.css/.less/.png格式的文件,如果没有经过declare的话是会提示语法错误的。
# 5.声明一个作用域
declare namespace API {
interface ResponseList { }
}
2
3
声明完之后在其他地方的 ts 就可以直接 API.ResponseList 引用到这个接口类型。
# 二、库的结构
如果我们要给一个库编写声明文件,首先第一步是识别库的结构。
模块系列:我们可以通过 require
或者 import/export
来判断该库是否属于模块系列。
全局库:全局库是无需使用 import
等语句导入,便可以在全局作用域下使用的库。有些库会暴露一个或多个全局变量来供我们使用。
现在,许多流行的全局库都是当作通用模块化方案UMD
的库来写的,且不容易与UMD
区分开来。在编写全局库的声明文件之前,一定要确保它们实际上并不是UMD
的库。UMD
的库往往会在文件的顶层使用typeof define
,typeof module
,typeof window
等来测试运行环境,如果我们看到使用了这些语句的,那么大概率就是UMD
的库(比如 day.js)。
# 三、库的依赖处理
# 1.全局库的依赖处理
如果我们的编写的库,依赖于其它的全局库,可以使用三斜杠指令 /// <reference types="xxx" />
来引入。
/// <reference types="someLib" />
declare function getThing(): someLib.something;
2
我们可以看到,全局库都是使用的declare
而不是export
,因此其声明的库无需导入,全局可用。
# 2.模块的依赖处理
如果我们的库依赖其他模块,可以通过 import
来导入该模块。
import * as moment from "moment";
declare function getThing(): moment;
2
# 3.对 UMD 库的依赖
对UMD
库的依赖也分为全局库(以UMD
方式构建的全局库) 和 UMD
库。
如果我们的库依赖与 UMD 的全局库,也使用三斜杆指令 /// <reference types="xxx" />
来引入。
/// <reference types="moment" />
declare function getThing(): moment;
2
如果依赖于其它的 模块 或者严格意义上的UMD
库 ,则使用import
来导入。
import * as someLib from "someLib";
注意
切勿使用三斜杠指令来引入UMD
库,因此,需要分清到底是使用了UMD
方式的全局库,还是实际上的UMD
库。