0%

【048】typescript:接口(interface)

比较官方的解释:接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。

我的理解:接口是一种约束行为,约束数据的结构。

简单使用

举个例,比如每个人都有名字和年龄,那么我把他定义成一个Person接口,如下:

1
2
3
4
interface Person {
name: string,
age: number
}

这个时候,我要使用这个Person接口了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 在这里会报错,因为Person接口里并没有sex这个属性,所以使用时不能有。
let person: Person = {
name: '小三',
age: 24,
sex: '男'
}

// 在这里也会报错,因为Person接口里缺少了age这个属性,所以使用时不能缺少它。
let person: Person = {
name: '小三',
}

// 应该是这样,接口里面有什么就用什么,不能多也不能少。
let person: Person = {
name: '小三',
age: 24
}

接口继承

那么问题来了,使用了Person后发现,Person还分了男人和女人,怎么办?

不慌,我们再写个男人和女人的接口,如下:

1
2
3
4
5
6
7
interface Man {
sex: '男'
}

interface Woman {
sex: '女'
}

写好了,这两个接口目前还是独立的,那么要怎么跟Person扯上关系呢?

分析一下,男人和女人都是人,那么自然是Person的一部分,如果Person是一级接口,那么ManWoman就是二级接口,我们可以使用继承(extends)将他们关联起来。即这个男人(女人)继承了人的属性。

1
2
3
4
5
6
7
interface Man extends Person {
sex: '男'
}

interface Woman extends Person {
sex: '女'
}

这个时候就可以正常使用了,如下:

1
2
3
4
5
6
7
8
9
10
11
let man: Man = {
name: '老王',
age: 30,
sex: '男'
}

let woman: Woman = {
name: '翠花',
age: 18,
sex: '女'
}

接口合并

再后来呀,我们发现人不仅仅有姓名和年龄,还有身高和体重,那么应该怎么补上去呢?

这个时候,可以有三种方法

  1. 第一种是直接在原来的Person接口上添加。
  2. 第三种是再添加一个Person接口,让两个接口合并在一起。
    现在说一下第二种(接口合并)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    interface Person {
    height: number,
    weight: number
    }
    let person: Person = {
    name: '小三',
    age: 18,
    height: 178,
    weight: 60
    }

[props: string]

写着写着发现,人还有手长腿长腰围胸围一堆属性,如果一直使用接口合并,肯定让人受不了。好在有[props: string],可以帮助我们减少这个烦恼。

1
2
3
4
5
6
7
8
9
10
11
interface Person {
[props: string]: any
}

let person: Person = {
name: '小三',
age: 18,
height: 178,
weight: 60,
waistline: 50
}

至于为什么使用any类型,因为我们无法确定下一个发现缺少的属性是number还是string,如果清楚知道缺少属性类型的话,也可以使用联合类型(|)。

1
2
3
interface Person {
[props: string]: number | string
}

添加函数

接口不仅可以添加属性,还可以添加函数。比如每个人都要吃东西,那么要用什么方法吃,是要大口大口吃还是小口小口吃。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface Person {
eat: () => void
}

let person: Person = {
name: '小三',
age: 18,
height: 178,
weight: 60,
waistline: 50,
eat: () => {
console.log('我要大口大口吃东西')
}
}

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 简单使用
interface Person {
name: string,
age: number
}

// 接口合并
interface Person {
height: number,
weight: number
}

// [props: string]
interface Person {
[props: string]: any
}

// 接口函数
interface Person {
eat: () => void
}

// 接口继承
interface Man extends Person {
sex: '男'
}

interface Woman extends Person {
sex: '女'
}

let person: Person = {
name: '小三',
age: 18,
height: 178,
weight: 60,
waistline: 50,
eat: () => {
console.log('我要大口大口吃东西')
}
}

let man: Person = {
name: '小三',
age: 18,
height: 178,
weight: 60,
waistline: 50,
eat: () => {
console.log('我是男人,我要大口大口吃东西')
}
}

let woman: Person = {
name: '翠花',
age: 18,
height: 178,
weight: 60,
waistline: 50,
eat: () => {
console.log('我是女人,我要小口小口吃东西')
}
}