TypeScript Learning 7 - 高级类型

交叉类型

字面理解是取类型的两个交集,而实际是取两个类型的并集,例如:

1
2
3
4
5
6
7
8
9
10
11
12
interface DogInterface {
run(): void
}

interface CatInterface {
eat(): void
}

let pet: DogInterface & CatInterface = {
run() {},
eat() {}
}

联合类型

联合类型就是指类型不确定,可能为指定的其中一个,例如:

1
2
3
4
5
let a: number | string = 1
// let a: number | string = '1'
// 字面量联合类型.
let b: 'a' | 'b' = 'a'
let c: 1 | 2 = 2

可辨识联合就是利用类型公共字段来创建类型保护,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface Square {
kind: 'square'
size: number
}
interface Rectangle {
kind: 'rectangle'
width: number
height: number
}

type Shape = Square | Rectangle

function area(s: Shape) {
switch (s.kind) {
case 'square':
return s.size * s.size
case 'rectangle':
return s.height * s.width
}
}

索引类型

使用索引类型,编译器就能够检查使用了动态属性名的代码。 例如,一个常见的JavaScript模式是从对象中选取属性的子集

1
2
3
function pluck (o, names) {
return names.map(n => o[n])
}

下面是如何在TypeScript里使用此函数,通过 索引类型查询和 索引访问操作符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function pluck <T, K extends keyof T>(o: T, names: K[]): T[K][] {
return names.map(n => o[n])
}

interface Person {
name: string
age: number
}

let person: Person = {
name: 'Jarid',
age: 35
}

let strings: string[] = pluck(person, ['name']) // ok, string[]

映射类型

我们可能有这种需求,把下面的接口可选属性都变成只读属性:

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

ts提供从旧类型创建新类型的一种方式 — 映射类型

1
2
// 使用.
type ReadonlyPerson = Readonly<Person>

条件类型

请查阅文档T_T!

使用感受

目前基本功能都看了,也在一个react全家桶里使用了,但结果对我本人来说挺不爽的
我知道有人写人会说,这玩意越用越爽,但我没有觉得
目前来看,类型应该是趋势,可是动态语言来的是灵活,ts就是想给js加个框来限制住,这个框我个人觉得过于复杂,如果你在你的团队想推广使用的话,你不得不考虑它的成本,你能否驾驭这个工具和承担这个成本都是要考虑的
当然,后面还是一直会用的,暂时也就是样了

欢迎留言讨论 ^_^ ~