声明文件
例如一般一个项目都会引入其他的依赖包(没有对应的声明文件),或者是在html中使用<script>标签引入的其他脚本,这时候在 ts 中使用时,就会报错。
这时候就需要书写对应的声明文件做类型补充,声明文件以 .d.ts 结尾。
一般第三方库都不需要我们自己写书面文件,其声明文件会包含在库中或可以通过 “@types/” + 三方库的名 下载对应的声明文件,例如
npm install @types/jquery --save-dev
如果以上都没有生效,则需要自己写对应的声明文件
全局声明文件
使用 declare 关键字
- declare var : 声明全局变量的类型
- declare function: 声明全局函数的类型
- declare class : 声明全局类的类型
- declare namespace : 声明全局带属性的对象
- interface / type : 声明全局类型
declare var
例如我们在项目中引入 jQuery 时,我们可以使用 全局变量 $
$('#id')
这时候 ts 编译器并不知道 $ 是什么东西
这时,我们就可以使用 declare var 来声明它的类型
declare var $: (tag: string) => any;
除了declare var,还可以使用 declare let,如果变量是只读的,那么可以使用 declare const。
像上面的例子,jquery 全局变量 $ 是不会改变的,而且是禁止修改的,那么我们的声明最好改成
declare const $: (tag: string) => any;
这样修改 $ 时,ts就会报错
declare function
除了全局的变量,还有全局函数
同样的,上面例子中 JQuery 的 $ 其实是个函数
那么便可以用 declare function 声明
declare function $(tag: string): any;
注意,声明语句中只能定义类型,不能有具体实现
declare class
同样的如果全局变量有个类,写对应的声明,同样的只能定义类型,不能定义具体实现
declare class User {
constructor(name: string)
name: string;
age: number;
}
// ts 中就可以正常使用
let myUser = new User()
declare namespace
如果全局变量有个对象,可以使用declare namespace声明全局带属性的对象
在 declare namespace 内部,可以直接使用 function、namespace、const、class 等来声明,而不需要在其前面加 declare
declare namespace myObject {
function show(s: string): string;
let myInfo: number;
class myClass {
constructor(n:string)
name: string
}
// 也可以嵌套 namespace
namespace secondLayer{
secondData
}
}
这样 ts 中就可以正常使用
console.log(myObject.myInfo.toFixed(2))
console.log(myObject.secondLayer.secondData.length)
myObject.show('')
new myObject.myClass('')
也可以直接创建嵌套的命名空间
declare namespace myObject.secondLayer {
secondData
}
interface 、 type
除了全局变量,有时候我们需要声明一个全局的类型,这时候可以在声明文件中使用 interface 和 type 声明
interface IGlobalInterface {
name: string
}
这样就可以在全局使用 IGlobalInterface 这个接口,type同理
声明的合并
例如页面中引入了 jquery
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
jq自己既是函数,其又有很多的属性
那么可以,
declare function jQuery(selector: string): any;
declare namespace jQuery{
function ajax(url: string, settings?: any): void;
}
同名的声明可以合并
通过声明合并,我们可以直接扩展全局变量
例如扩展 String 类型
interface String {
myStringFunction(): string;
}
'xxx'.myStringFunction()
也可以使用 declare namespace 给已存在的命名空间新增其他类型声明
模块的声明文件
declare module
declare module 可以声明模块
例如常用的 js-cookie npm包
import Cookies from 'js-cookie'
Cookie.get('token') // error 不存在属性"get"
可以写对应的声明文件
// 这里只是部分类型声明示例,并不是 js-cookie 完整的类型声明
declare module 'js-cookie'{
export function get(x:string, option?:{ [key:string]: string }):void
}
如果是需要扩展原有模块的话,需要在类型声明文件中先引用原有模块,再使用 declare module 扩展原有模块
例如:
import * as thirdPartyModule from 'thirdPartyModule';
declare module 'thirdPartyModule' {
export function otherAttr(): string;
}