类型声明
- 声明文件可以让我们不需要将JS重构为TS,只需要加上声明文件就可以使用系统
- 类型声明在编译的时候都会被删除,不会影响真正的代码
1 普通类型声明
// 其它类型声明
declare let name: string; // 变量
declare let age: number; // 变量
declare function getName(): string; // 方法
declare class Animal { name: string }; // 类
interface Peerson { // 声明接口
name: string
}
type Student = Peerson | string; // 声明类型
2 外部枚举
- 外部枚举是使用
declare enum
定义的枚举类型 - 外部枚举用来描述已经存在的类型的形状
declare const enum Seasons {
Spring,
Summer,
Autumn,
Winter
}
let seasons: Seasons[] = [
Seasons.Spring,
Seasons.Summer,
Seasons.Autumn,
Seasons.Winter,
]
3 namespace 命名空间
4 类型声明文件
- 我们可以把类型声明放在一个单独的类型声明文件中(通常是 typings 文件夹下的 xx.d.ts 文件)
- 可以在类型声明文件中使用类型声明
- 文件命名规范为
*.d.ts
- 观看类型声明文件有助于了解库的使用方式
下面举个例子:
- 我们在 typings 文件夹下的 jquery.d.ts 文件,进行类型声明。
- 配置 tsconfig.json 文件,
- 最后在 test.js 文件中使用:
4.1 jquery.d.ts
typings\jquery.d.ts
declare const $: (selector: string) => {
click(): void
width(length: number): void
}
// 如果说需要导入一个模块,是JS的,没有官方的类型声明文件,也没有第三方的类型声明文件,自己也不想为他写声明文件
declare module 'parse-headers'; // 这里用 'parse-headers' 模块举例,偷懒的写法,相当于定义它的类型是 any
4.2 tsconfig.json
- 如果类型声明文件没有起作用,需要注意在tsconfig.json文件下的"include"配置项,
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2015",
"outDir": "lib",
// ...
},
"include": [ // 告诉 TS 需要编译的目录,默认会编译所有根目录下的文件
"src/**/*", // 告诉 TS 只需要编译 src 目录下的所有 .ts 文件
"typings/**/*" // 告诉 TS 还需要编译 typings 目录下的所有 .d.ts 文件
]
}
4.3 test.js
$("#root").click();
$("#root").width(100);
5 第三方声明文件
- 可以安装使用第三方的声明文件
- @types是一个约定的前缀,所有的第三方声明的类型库都会带有这样的前缀
- JavaScript 中有很多内置对象,它们可以在 TypeScript 中被当做声明好了的类型
- 内置对象是指根据标准在全局作用域(Global)上存在的对象。这里的标准是指 ECMAScript 和其它环境(比如 DOM)的标准
- 这些内置对象的类型声明文件,就包含在 TypeScript 核心库的类型声明文件 中
5.1 使用jquery
// 对于common.js风格的模块必须使用 import * as
import * as jQuery from 'jquery';
jQuery.ajax('/user/1');
5.2 安装声明文件
cnpm i @types/jquery -S
5.3 自己编写声明文件(不太现实,太多了)
types\jquery\index.d.ts
declare function jQuery(selector: string): HTMLElement;
declare namespace jQuery{
function ajax(url: string): void
}
export default jQuery
配置:tsconfig.json 文件
- 果配置了
paths
,那么在引入包的时候会自动去paths
目录里找类型声明文件 - 在 webpack 中,我们可以通过配置 alias 的形式来为项目里的文件做映射。在
tsconfig.json
中,我们同样也可以做路径的映射 - 在 tsconfig.json 中,我们通过
"compilerOptions"
里的paths
属性来配置路径映射。
tsconfig.json
"compilerOptions": {
"baseUrl": "./", // 使用 paths 属性的话必须要指定 baseUrl 的值
"paths": {
"*": ["types/*"] // 表示在导入任何模块的时候,都先去读取 types 文件下的所有文件(这里指声明文件)
}
}
5.4 npm声明文件可能的位置
- node_modules/jquery/package.json
- "types": "types/xxx/d/ts"
- node_modules/jquery/index.d.ts
- node_modules/@types/jquery/index.d.ts
6 扩展全局变量的类型
6.1 扩展局部变量类型
// 可以直接使用接口对已有类型进行扩展
interface String {
double():string
}
String.prototype.double = function () {
return this as string + this;
}
let str = '123';
console.log(str.double()) // '123123'
6.2 模块内全局扩展
declare global{
interface String {
double():string;
}
}
// 声明全局表示对全局进行扩展
7 和并声明
7.1 合并类型声明
// 同一名称的两个独立声明会被合并成一个单一声明,合并后的声明拥有原先两个声明的特性。
// 同名接口合并
interface Animal {
name:string
}
interface Animal {
age:number
}
let a:Animal = {name:'456',age:10};
7.2 使用命名空间扩展类、方法、枚举类型
// 命名空间的合并
// 扩展类
class Form {}
namespace Form {
export const type = 'form'
}
// 扩展方法
function getName(){}
namespace getName {
export const type = 'form'
}
// 扩展枚举类型
enum Seasons {
Spring = 'Spring',
Summer = 'Summer'
}
namespace Seasons{
export let Autum = 'Autum';
export let Winter = 'Winter'
}
8 交叉类型合并
import { createStore, Store } from 'redux';
type StoreWithExt = Store & {
ext:string
}
let store:StoreWithExt
8 生成声明文件
配置tsconfig.json 中 "declaration": true 生成声明文件