# Typescript 高阶
# interface
和 type
(类型别名 type alias
) 的区别
- 属性继承
// interface 属性继承 Extending Types
interface Animal {
name: string
}
interface Bear extends Animal {
honey: boolean
}
const bear = getBear()
bear.name
bear.honey
// type 交叉类型 Intersections Types
type Animal = {
name: string
}
type Bear = Animal & {
honey: boolean
}
const bear = getBear();
bear.name;
bear.honey;
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface
可以extends
, 但type
是不允许extends
和implement
的,但是type
却可以通过交叉类型实现interface
的extend
行为,并且两者并不是相互独立的,也就是说interface
可以extends type
,type
也可以与interface
类型交叉 。
TIP
这两种方式在合并类型上看起来很相似,但实际上还是有很大的不同。最原则性的不同就是在于冲突怎么处理,这也是你决定选择那种方式的主要原因。
interface Colorful {
color: string;
}
interface ColorfulSub extends Colorful {
color: number
}
// Interface 'ColorfulSub' incorrectly extends interface 'Colorful'.
// Types of property 'color' are incompatible.
// Type 'number' is not assignable to type 'string'.
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
使用继承的方式,如果重写类型会导致编译错误,但交叉类型不会:
interface Colorful {
color: string;
}
type ColorfulSub = Colorful & {
color: number
}
1
2
3
4
5
6
7
2
3
4
5
6
7
这个时候虽然编译不会报错了,那么color
的类型是啥呢。答案是never
,取得是 string
和 number
的交集。
- 重复添加属性(声明合并)
// interface (Adding new fields to an existing interface)
interface Animal {
name: string
}
interface Animal {
age: number
}
const me: Animal = {
age: 10,
name: "linjiaheng"
}
// type (A type cannot be changed after being created)
type Animal = {
name: string,
}
type Animal = {
age: 20,
}
// Error: Duplicate identifier 'Animal'.
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
type
可以声明基本类型别名,联合类型,元组等类型,还可以使用typeof
获取实例的类型进行赋值。
// 当你想获取一个变量的类型时,使用 typeof
let div = document.createElement('div');
type B = typeof div
1
2
3
2
3
# 编写类型安全的代码
基础:<<Effective Typescript: N个使用技巧>> (opens new window) 高级:<<Typescript 类型系统与函数式编程>> (opens new window)