1. 基础:
TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
/*
* 1. 写法: interface 接口名称 { ...接口规则}
* 2. 为我们提供一种方式来定义某种结构,ts按照这种结构来检测数据
* 3. 接口中定义的规则只有抽象描述,不能有具体的值与实现的
*
*/
interface Options { // 1. 定义一个接口规则 Options
width: number,
height: number
}
function fn(opts: Options) { // 2. 使用 接口规则Options 对函数参数进行类型检测
let obj = opts;
console.log(obj.width)
}
fn({ height: 200, width: 100 }); // ok
// fn({height:200}); // error 参数不能缺少
// fn({height:200,width:100,str:300}); // error 不能有额外参数
2. 可选结构:
interface Options { // 1. 定义一个接口规则 Options
width: number,
height: number,
color?: string // ? 表示 该属性可选
}
function fn(opts: Options) { // 2. 使用 接口规则Options 对函数参数进行类型检测
let obj = opts;
console.log(obj.width)
}
fn({ height: 200, width: 100 }); // ok
fn({ height: 200, width: 100, color: 'red' }); // ok
3. 检测约束:
/*
* 有时候,希望检测不必要这么复杂,可以忽略某些检测
*/
interface Options {
width: number,
height: number,
}
function fn(opts: Options) {
let obj = opts;
console.log(obj.width)
}
// 1. 正常检测:必须 传入 height width
fn({ height: 200, width: 100 }); // ok
// 2. 通过 as 断言,减少 传入
fn({ height: 200 } as Options); // ok
// 3. 通过变量,增加 传入
let obj = {
height: 100,
width: 200,
a: 1
}
fn(obj); // ok
4. 索引签名:
/*
* 索引签名:
* 1. 为数据定义一组具有某种特性的key的数据
* 2. 索引key的类型只能是 number 和 string 两种
*/
interface Options { // 接口约束 -> 对象的key为数字
[attr: number]: any,
length: number
}
function fn(opt: Options) { }
fn({
0: 100,
1: 200,
3: 300,
length: 3
})
interface Options2 { // 接口约束 -> 对象的key为字符串
[attr:string]:any
}
function fn2 (opt:Options2){}
fn2({
a:'aaa',
b:'bbb'
})
5. 函数类型的接口:
/*
* 函数类型接口
*/
// 1. 约束 -> 属性fn值的类型为函数
interface Options1 {
fn: Function
}
let o: Options1 = {
fn: function () { }
}
// 2. 约束 -> 定义函数的结构
interface Options2 {
(x: number, y: number): number
}
let fn: Options2 = function (x: number, y: number): number {
return x + y
}
// 3. 约束 -> 定义一个接受一个MouseEvent类型参数的函数结构
interface MouseEventCallBack {
(e: MouseEvent): any
}
let fn2: MouseEventCallBack = function (a: MouseEvent) { }
document.onmouseenter = fn2;
// 4. 约束 -> 定义一个接受一个Response类型参数的函数结构
interface ResponseCallBack {
(rs: Response): any
}
function todo(callback: ResponseCallBack) {
callback(new Response);
}
fetch('url').then( (a: Response) => {
a.json();
} );
6. 类接口:
/**
* 1. 类接口: 让某个类去符合某种契约
* 2. 类可以通过 implements 关键字去实现某个接口
* 3. implements 某个接口的类必须实现这个接口中确定所有的内容
* 4. 一个类只能有一个父类,但是可以implements多个接口,多个接口使用逗号分* 隔
*/
interface IsSuper {
fly(): void
}
interface IsSuper2 {
eat(): void
}
class Man {
constructor(public name: string) { }
}
// 类SuperMan 继承 Man类 并实现 类接口IsSuper、IsSuper2 约束
class SuperMan extends Man implements IsSuper, IsSuper2 {
fly() { console.log('to fly') }
eat() { console.log('to eat') }
}
7. 案例:
interface HttpOptions {
method: string,
url: string,
isAsync: boolean
}
interface HttpResponseData {
code: number,
data: any
}
function http(options: HttpOptions) {
let opt: HttpOptions = Object.assign({
method: 'get',
url: '',
isAsync: true
}, options);
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open(opt.method, opt.url, opt.isAsync);
xhr.onload = function () {
let data: HttpResponseData = JSON.parse(xhr.responseText);
resolve(data);
}
xhr.onerror = function () {
reject({
code: xhr.response.code,
message: 'error'
})
}
xhr.send();
})
}
http({
method: 'get',
url: '',
isAsync: true
}).then((rs: HttpResponseData) => {
console.log(rs.code)
})