# 高级类型一
WARNING
- 交叉类型
- 联合类型
- 类型保护
- null 和 undefined
- 类型保护和类型断言
- 类型别名
- 字面量类型
- 枚举成员类型
- 可辨识联合
交叉类型 & 表示 (并集)
let mergeAd = <T, U> (arg1: T, arg2: U) : T & U => {
let res = {} as T & U
res = Object.assign(arg1, arg2)
return res
}
1
2
3
4
5
6
2
3
4
5
6
联合类型 type1 | type2 | type3
let getLeng = (content: string | number): number => {
if (typeof content === 'string') {
return content.length
} else {
return content.toString().length
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
类型保护
let valueArr = [123, 'abc']
let getRandomValue = () => {
let num = Math.random() * 10
if (num < 5) {
return valueArr[0]
} else {
return valueArr[1]
}
}
let item = getRandomValue()
function isString (value: string | number): value is string {
return typeof value === 'string'
}
// 类型保护
if (isString(item)) {
console.log(item.length)
} else {
console.log(item.toFixed())
}
// string / boolean / number / symbol
if (typeof item === 'string') {
console.log(item.length)
} else {
console.log(item.toFixed())
}
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
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
instanceof
class CreatedByClass1 {
age = 12
}
class CreatedByClass2 {
name = '小于'
}
function getRandomNumber() {
return Math.random() < 0.5 ? new CreatedByClass1() : new CreatedByClass2()
}
let item1 = getRandomNumber()
if (item1 instanceof CreatedByClass1) {
console.log(item1.age)
} else {
console.log(item1.name)
}
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
null 和 undefined
他们是任何类型的子类型。
// 关闭严格模式,以下是可以的
let values = '112'
values = undefined
1
2
3
2
3
string | undefined 、 string | null 、 string | null | undefined 是三种不同的类型
// y 是 number | undefined 的联合类型
let sumFn = (x: number, y?: number) => {
return x + (y || 0)
}
1
2
3
4
2
3
4
类型保护和类型断言
let getLength2 = (value: string | null) : number => {
if (value === null) {
return 0
} else {
return value.length
}
// 等同于上面的 if else
return (value || '').length
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
手动指定
function getSplicedStr (num: number | null): string {
function getRes (prefix: string) {
// return prefix + num?.toFixed().toString()
// ! 表示不为 null ? 表示存在的时候
return prefix + num!.toFixed().toString()
}
num = num || 0.1
return getRes('xiao')
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
类型别名 type ,取了一个名字
type TypeStr = string
let typestr: TypeStr
1
2
2
type PositionType <T> = { x: T, y: T }
let position1: PositionType<number> = {
x: 1,
y: -1
}
1
2
3
4
5
2
3
4
5
type 为接口取了别名后,不能使用 extends 、 implements
接口和类型别名有时候很像
type Alias = {
num: number
}
interface InterAli {
num: number
}
let alias: Alias = {
num: 12
}
let alias2: InterAli = {
num: 13
}
// 可以直接赋值,说明类型兼容
alias = alias2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
字面类型 (字符串字面量和数字字面量)
type Name = 'xiaoyu'
let val1: Name = 'hhh' // 此处只能是 xiaoyu
1
2
3
4
2
3
4
// 字符串字面量
type Direction = 'north' | 'east' | 'south' | 'west'
function getDirectionFirst (direction: Direction) {
return direction.substr(0, 1)
}
// 只能north east south west 中的一个
getDirectionFirst('north')
1
2
3
4
5
6
7
2
3
4
5
6
7
// 数字字面量
type Age = 18
interface InfoIter {
name: string,
age: Age
}
let info1: InfoIter = {
name: 'xiaoyu',
age: 18 // 必须是18
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
枚举成员类型,作为类型的枚举需要满足以下条件
- 不带初始值的枚举成员
- 成员的值仅仅是字符串字面量
- 成员仅是数值字面量
可辨识联合的两要素
- 具有普通单例类型的属性
- 一个类型别名包含了哪些类型的联合
interface Square {
kind: 'square',
size: number
}
interface Rectangle {
kind: 'rectangle',
height: number,
width: number
}
interface Circle {
kind: 'circle',
radius: number
}
// 包含3个接口的联合
type Shape = Square | Rectangle | Circle
function assertNever (value: never): never {
throw new Error('never')
}
function getArea (s: Shape): number {
switch (s.kind) {
case "square":
return s.size * s.size
break;
case "rectangle":
return s.height * s.width
break;
case "circle":
return Math.PI * s.radius ** 2
break;
default: return assertNever(s)
}
}
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
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