# 高级类型一

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

联合类型 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

类型保护

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

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

nullundefined

他们是任何类型的子类型。

// 关闭严格模式,以下是可以的
let values = '112'
values = undefined
1
2
3

string | undefinedstring | nullstring | null | undefined 是三种不同的类型

// y 是 number | undefined 的联合类型
let sumFn = (x: number, y?: number) => {
	return x + (y || 0)
}
1
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

手动指定

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

类型别名 type ,取了一个名字

type TypeStr = string
let typestr: TypeStr
1
2
type PositionType <T> = { x: T, y: T }
let position1: PositionType<number> = {
	x: 1,
	y: -1
}
1
2
3
4
5

type 为接口取了别名后,不能使用 extendsimplements

接口和类型别名有时候很像

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

字面类型 (字符串字面量和数字字面量)


type Name = 'xiaoyu'
let val1: Name = 'hhh' // 此处只能是 xiaoyu

1
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
// 数字字面量
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

枚举成员类型,作为类型的枚举需要满足以下条件

  • 不带初始值的枚举成员
  • 成员的值仅仅是字符串字面量
  • 成员仅是数值字面量

可辨识联合的两要素

  • 具有普通单例类型的属性
  • 一个类型别名包含了哪些类型的联合
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