TypeScript基础—并集unionTypes联合类型

75 阅读2分钟

类型判断.PNG

1、使用typeof进行类型收窄(基本类型)

type  A1 = number;
type  B1 = string;
type  C1 = A1 | B1;
const c1: C1 = '[]'


type A2 = { name: string }
type B2 = { age: number }
type  C = A2 | B2
const c: C = {
    age: 12
}

const f1 = function (a: number | string) {
    // '既不能把a当作number,也不能当作string'
    if (typeof a === "number") {
        // 此时a的类型是number
        a.toFixed(2)
    } else if (typeof a === "string") {
        a.substr(1, 1)
    } else {
        throw new Error('Never do this')
    }
}
// instanceof
const f2 = function (a: Date | Date[]) {
    // '既不能把a当作number,也不能当作string'
    if (a instanceof Date) {
        // 此时a的类型是number
        a.getDay()
    } else {
        // 此时是数组
        a[0].getDay()
    }
}

复杂的数据类型使用typeof关键字之后都会变为对象,所以typeof有一定的局限性。

typeof.PNG

2、使用in关键字进行类型收窄

in关键字表示某一个属性是否位于一个对象的实例当中,例如name in a


/**
 * 一旦做了类型联合就要进行类型收窄
 */

type Person = {
    name: string
}
type  Animal = {
    x: string
}
// 使用in作类型收窄,但是只适用于部分对象,
const f3 = (a: Person | Animal) => {
    if ('name' in a) {
        a // Person
    } else if ('x' in a) {
        a // Animal
    } else {
        a
    }
}
// 使用逻辑进行类型收窄
const f4 = (a?: string[]) => {
    if (a) {
        a // string[]
    }
}
const f5 = (x: string | number, y: string | boolean) => {
    if (x === y) {
        x // string
        y // string
    } else {

    }
}

3、区分ts类型的完全之法,类型谓词/类型判断 is

// 区分ts类型的完全之法,类型谓词/类型判断  is    优点 :支持所有的TS类型
type Rect = {
    height: number
    width: number
}
type Circle = {
    center: [number, number];
    radius: number
}
const f6 = (a: Rect | Circle) => {
    if (isRect(a)) {
        a // Rect
    } else {
        a // Circle
    }
}

// 判断他是不是Rect类型
/**
 * 必须写成function的形式
 * @param x
 */
function isRect(x: Rect | Circle): x is Rect {
    return 'height' in x && 'width' in x
}

4、给对象添加属性区分不同类型

// 更简单的方法? a.kind区分a的类型

//通过添加一个kind字段识别不同的类型
interface Circle1 {
    kind: 'circle',
    value: number
}

interface Square1 {
    kind: 'square',
    value: number
}

type Shape = Circle1 | Square1
const f7 = (a: Shape) => {
    if (a.kind === 'circle') {
        a // A
    } else {
        a // B
    }
}
const button = document.getElementById('xxx')
button?.addEventListener('click', (e: Event) => {
    //e as MouseEvent
})

// any并不是表示的所有类型, 类型一旦联合变量就不能使用了,需要做类型收窄。

// unknown是所有类型的联合,需要进行类型收窄每次可以选择一个类型。
const f8 = (a: unknown) => {
    if (typeof a === 'string') {
        a //string
    } else if (a instanceof Date) {
        a.getTime() // Date
    } else if (typeof a === 'undefined') {
        a
    }
}

5、类型系统的交集

// *--------------------*
// 类型系统的交集

type 有左手的人 = {
    left: string
}
type 有右手的人 = {
    right: string
}

const a: 有左手的人 = {
    left: '左',
    // right:'右' // error
}
const doubleHands = {
    left: '左',
    right: '右'
}
delete doubleHands.right
const b: 有左手的人 = doubleHands // ok


// 接口也能交集

interface Colorful {
    color: string
}

interface CircleFul {
    radius: string
}

type  CircleColorful = Colorful | CircleFul

type Person1 = {
    id: string
    name: string
    age: number
}
type User = Person1 & {
    // id:number;
    email: string
}
// 假如两个属性的类型冲突
const u: User = {
    // id:1  id的类型是never
    id: '1',
    name: '1',
    age: 1,
    email: '1'
}

// 假如两个type交集冲突,函数的交集会得到函数的并集。
type AA = {
    method:(n:number) => void
}
type BB = {
    method:(n:Date) => void
} & AA

const bb:BB = {
 method:(n) =>{
     console.log(n)
 }
}