联合类型的使用
// 例子 1
type A1 = number
type A2 = string
type A3 = A1 | A2
const a: A3 = '1'
// 例子 2
type A1 = { // 表示 name 为 string 的所有对象,并不代表该对象只有 name 属性 { name: 'rourou', gender: '女' } 也属于 A1
name: string
}
type A2 = {
age: number
}
// A3 是 A1 和 A2 的并集,即可以只包含 name 属性、age 属性或者name 和 age 都包含
type A3 = A1 | A2
const a: A3 = {
name: 'rourou'
}
const b: A3 = {
age: 18
}
const c: A3 = {
name: 'rourou',
age: 18
}
如何区分联合类型的具体类型(类型收窄)
-
使用 typeof
type Fn = (a: number | string) => void const f1: Fn = (a) => { if (typeof a === 'number') { a.toFixed(2) // 这里 a 一定是 number } else if (typeof a === 'string') { a.split(',') // 这里 a 一定是 string } else { console.log('never') } }注: typeof 只能判断
string number boolean bigint symbol undefined object function,对于对象类型没办法具体判断 -
使用 instanceof 来区分
type Fn = (a: Date | Date[]) => void const f1: Fn = (a) => { if (a instanceof Date) { console.log(a) } else if (a instanceof Array) { console.log(a) } else { console.log('never') } }注: instanceof 只能区分有构造函数的对象,不能区分基本类型以及 ts 独有的类型
-
使用 in 来收窄类型
type Person = { name: string } type Animal = { age: number } type Fn = (a: Person | Animal) => void const f1: Fn = (a) => { if ('name' in a) { console.log('Person') } else if ('age' in a) { console.log('Animal') } else { console.log('never') } } -
使用 js 中的判断类型函数来区分
type Fn = (a: string[] | string) => void const f1: Fn = (a) => { // Array.isArray(a) 就是判断类型的函数 if (Array.isArray(a)) { console.log(a) } else if (typeof a === 'string') { console.log(a) } else { console.log('never') } } -
使用逻辑来收窄
type Fn = (a?: string) => void const f1: Fn = (a) => { if (a) { // string console.log(a) } else { // undefined console.log(a) } } -
使用类型谓词 is
type Rect = { width: number, height: number } type Circle = { center: [number, number], radius: number } // x is Rect 不可写成 boolean,这样做不到类型收窄 const isRect = (x: Rect | Circle): x is Rect => { return 'width' in x && 'height' in x } function isCircle(x: Rect | Circle): x is Circle { return 'center' in x && 'radius' in x } const f1 = (x: Rect | Circle): void => { if (isRect(x)) { x } else if (isCircle(x)) { x } } -
可辨别联合(即定义一个可以区分二者的键值对)
// 这里使用的是 kind 来区分 type Circle = { kind: 'circle', radius: number } type Square = { kind: 'square', width: number } const f1 = (x: Square | Circle): void => { if (x.kind === 'circle') { x } else if (x.kind === 'square') { x } } // 比 in 更强大 // 这里 Circle1 2 都有 kin type Circle1 = { kind: 'circle1', radius?: number } type Circle2 = { kind: 'circle2', radius?: number } const f1 = (x: Circle1 | Circle2): void => { }