interface用来描述数据(对象、数组、函数)应该符合哪些规范,利用interface可以规范对象的属性、值得类型和范围、数组的成员类型、函数的参数和返回值类型。
1. 对象类型接口
1.1 基础用法
首先定义一个对象类型接口,接口名为NameInfo,包含两个属性,分别为firstName和lastName,属性值均为string类型。
interface NameInfo {
firstName: string,
lastName: string
}
随后用NameInfo接口声明一个myName对象:
const myName: NameInfo = {
firstName: 'Kael',
lastName: 'Z'
}
以下例子会在编译时报错,因为:
- lastName属性值不是接口规定的string型
- 声明myName时添加了一个接口未定义的middleName属性
- 声明中缺失 firstName | lastName 中的任意一个
const myName: NameInfo = {
middleName: 'Alex', // error
lastName: 2 // error
}
1.2 设置可选属性
如果允许对象接口中的某个属性可传也可不传,可以将这个属性设置为可选属性,具体操作仅需在接口属性名后加 ‘ ? ’ 即可。这样在用接口声明对象的时候,即使缺失了这个属性也不会报错:
interface Car {
color: string,
brand?: string,
}
const car: Car = {
// brand为可选属性,因此这里没有brand也不会报错
color: 'red'
}
1.3 设置索引签名
设置索引签名,可以在传入多余属性时仍可执行,绕过多余属性检测。如下所示,在定义Car接口时,定义了一个空的属性,属性名为string类型,属性值为any类型。这样在声明car2对象时,即可传入其他属性值。
interface Car {
color: string,
brand?: string,
[prop: string]: any // 属性名为string类型,属性值为any类型
}
const car2: Car = {
color: 'red',
brand: 'Buick',
height: 200,
length: 500
}
1.4 设置只读属性
定义接口时,在属性名前加readonly,则该属性变为只读属性。如果后续要修改对象中此属性的值时会报错。
interface Person {
readonly name: string,
age: number
}
const jack: Person = {
name: 'Jack',
age: 30
}
Jack.name = 'Lisa' // error
2.数组类型接口
数组类型接口的用法很简单,接口中定义了成员的数据类型后,实例化的数组成员就必须满足类型检测:
interface ArrInter {
0: number,
readonly 1: string
}
const array1: ArrInter = [1, 'a']
同时可以看到上面的例子中,数组类型接口也支持设置只读属性,如果要修改的某一项数据是只读的,编译器同样会抛出错误:
array1[1] = 'b' // error
3.函数类型接口
我们来定义一个名为addFunc的函数类型接口,接收num1和num2两个number类型参数,并返回number类型的结果:
interface addFunc {
(num: number, num2: number): number
}
const add: AddFunc = (n1, n2) => n1 + n2
add(1,'2') // error
4.索引类型
对象、数组、函数内部都存在索引,我们可以给索引设置类型范围,从而对索引的类型进行检测。上面提到的索引签名就是索引类型的实践。
interface Role {
[id: number]: string,
}
let role1: Role = {
0: 'admin'
}
4.接口的继承
与es6中的类一样,interface也可以实现继承:
interface Father {
sex: string
}
interface Son extends Father {
age: number
}
const son: Son = {
age: 18,
sex: 'male'
}
5.混合类型接口 TS在3.1版本后支持了混合类型接口。比如在JS中,函数除了拥有函数表达式外,还可以在函数上挂一些其他的属性,现在TS也可以实现同样的效果。如下面的例子,实现了一个类似JS中的闭包的效果:
interface Counter {
(): void, // 定义一个没有参数的函数,返回值为void类型
count: number
}
const getCounter = (): Counter => {
const c = () => c.count++
c.count = 0
return c
}
const counter: Counter = getCounter()
counter()
console.log(counter.count) // 1
counter()
console.log(counter.count) // 2
counter()
console.log(counter.count) // 3