TS学习笔记2:interface接口

147 阅读3分钟

点击此处即可查看本文所属专栏的所有文章

interface用来描述数据(对象、数组、函数)应该符合哪些规范,利用interface可以规范对象的属性、值得类型和范围、数组的成员类型、函数的参数和返回值类型。

1. 对象类型接口

1.1 基础用法

首先定义一个对象类型接口,接口名为NameInfo,包含两个属性,分别为firstName和lastName,属性值均为string类型。

interface NameInfo {
    firstName: string,
    lastName: string
}

随后用NameInfo接口声明一个myName对象:

const myName: NameInfo = {
    firstName: 'Kael',
    lastName: 'Z'
}

以下例子会在编译时报错,因为:

  1. lastName属性值不是接口规定的string型
  2. 声明myName时添加了一个接口未定义的middleName属性
  3. 声明中缺失 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: 200length: 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