八、高级类型

# 八、高级类型
# 交叉类型与联合类型
# 交叉类型:取所有类型的并集
# 联合类型:声明的类型并不确定,可以为多个类型中的一个
interface DogInterface {
run(): void
}
interface CatInterface {
jump(): void
}
let pet: DogInterface & CatInterface = {
run() {},
jump() {}
}
let aas: number | string = 'a'
let bbs: 'a' | 'b' | 'c'
let ccs: 1 | 2 | 3
class Dogs implements DogInterface {
run() {}
eat() {}
}
class Cats implements CatInterface {
jump() {}
eat() {}
}
enum Master { Boy, Girl }
function getPet(master: Master) {
let pet = master === Master.Boy ? new Dogs() : new Cats()
pet.eat()
return pet
}
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: 'rectangle';
width: number;
height: number;
}
interface Circle {
kind: 'circle',
r: number
}
type Shape = Square | Rectangle | Circle
function area(s: Shape) {
switch (s.kind) {
case "square":
return s.size * s.size
case "rectangle":
return s.height * s.width
case "circle":
return Math.PI *s.r ** 2
default:
return ((e: never) => {throw new Error(e)})(s)
}
}
console.log(area({kind: 'circle', r: 1}))
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
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
# 索引类型
let objone = {
a: 1,
b: 2,
c: 3
}
// function getValues(obj: any, keys: string[]) {
// return keys.map(key => obj[key])
// }
function getValues<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
return keys.map(key => obj[key])
}
console.log(getValues(objone, ['a', 'b']))
console.log(getValues(objone, ['e', 'f']))
// keyof T 索引类型的查询操作符
interface Obj {
a: number,
b: string
}
let key: keyof Obj
// T[K]
let value: Obj['a']
// T extends U
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 Obj {
a: string;
b: number;
c: boolean;
}
// 所有接口属性只读
type ReadonlyObj = Readonly<Obj>
// 所有接口属性可选
type PartialObj = Partial<Obj>
// 抽取绑定的子集
type PickObj = Pick<Obj, 'a' | 'b'>
// 以上三种映射类型,官方统称同态,只会作用于obj的属性,不会引入新的属性
// 非同态的
type RecordObj = Record<'x' | 'y', Obj>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 条件类型
由条件表达式所决定的类型
// T extends U ? X : Y
type TypeName<T> =
T extends string ? 'string' :
T extends number ? 'number' :
T extends boolean ? 'boolean' :
T extends undefined ? 'undefined' :
T extends Function ? 'function' :
"object";
type T1 = TypeName<string>
type T2 = TypeName<string[]>
// (A | B) extends U ? X : Y
// (A extends U ? X : Y) | (B extends U ? X : Y)
type T3 = TypeName<string | string[]>
type Diff<T, U> = T extends U ? never : T
type T4 = Diff<"a" | "b" | "c", "a" | "e">
// Diff<"a", "a" | "e"> | Diff<"b", "a" | "e"> | Diff<"c", "a" | "e">
// never | "b" | "c"
// "b" | "c"
type NotNull<T> = Diff<T, undefined | null>
type T5 = NotNull<string | number | undefined | null>
// Exclude<T, U>
// NonNullable<T>
// Extract<T, U>
type T6 = Extract<"a" | "b" | "c", "a" | "e">
// ReturnType<T>
type T7 = ReturnType<() => string>
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
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
上次更新: 2021/04/22, 00:08:06