TypeScript学习(五)

1.TS的联合类型(并集)

但是对于 const f1 = (a:number | string) = > { ...... },如果不做处理的话,在方法体内就既不能把a当做number使用,也不能把a当做string使用。所以想要使用联合类型的话,就必须想办法把类型区分开来

JS中区分类型的方法(JS中的类型收窄(Narrowing)):

1.使用typeof来区分类型 

const f1 = (a:number | string) => {
    if(typeof a === 'number') {
        a.toFixed(2) // 此时a类型为number
    } else if (typeof a === 'string') {
        a.split(',') // 此时a类型为string
    }
}

typeof的局限性:

 

 2.使用instanceof来区分类型

const f1 = (a:Date | Date[]) => {
    if(a instanceof Date) {
        a // 此时a为Date
    } else {
        a // 此时a为Date[]
    }
}

 instanceof的局限性:

1.不支持string、number、boolean...

在TS中使用  if(a instanceof String)会报错

解决该问题可采用与 typeof 混合使用:

const f1 = (a:string | Date | Date[]) => {
    if ( typeof a === 'string') {
        a // 此时a为string
    } else if ( a instanceof Date) {
        a // 此时a为Date
    } else {
        a // 此时a为Date[]
    }
}

2.不支持TS独有的类型

type Person = {
    name:string
}
type Animal = {
    age:number
}
const f1 = (a:Person | Animal) {
    if(a instanceof Person) { // 报错
        a    
    }
}

3.使用 in 来收窄类型

type Person = {
    name:string
}
type Animal = {
    age:number
}
const f1 = (a:Person | Animal) {
    if('name' in a) { 
        a // 此时a为Person
    } else if ('age' in a) {
        a // 此时a为Animal
    }
}

in 的局限性: 只适用于部分对象

4.使用JS中判断类型的函数来区分

 5.使用JS中的逻辑来收窄类型

总结:无论使用JS中的何种区分类型的方法,都会有相应的局限性,故应该使用TS中的区分类型的完全方法。

TS中区分类型的方法:

1.类型谓词/类型判断 is:

type Rect = {
    height:number,
    width:number
}
type Circle = {
    center: [number,number],
    radius: number
}
type Shape = Rect | Circle

const f1 = (s:Shape) => {
    if (isRect(s)) {
        console.log(s.height) // 此时s为Rect
    } else if (isCircle(s)) {
        console.log(s.center) // 此时s为Circle
    }
}

function isRect (x:Rect | Circle): x is Rect {
    return 'height' in x && 'width' in x
}
function isCircle (x:Rect | Circle): x is Circle {
    return 'center' in x && 'radius' in x
}

is的优点:支持所有TS类型;is的缺点:写法麻烦

 2.可辨别联合x.kind:

type Circle = {kind:'Circle', center:[number,number]}
type Square = {kind:'Square',sideLength:number}
type Shape = Circle | Square

const f1 = (a:Shape) => {
    if (a.kind === 'Circle') {
        a // 此时a为Circle
    } else if (a.kind === 'Square') {
        a // 此时a为Square
    }
}

优点:让复杂类型的收窄变成简单类型的对比

要求:T=A | B | C | D | ...

1. A、B、C、D...有相同属性kind或其他  ;2.kind的类型是简单类型 ;3.各类型中的kind可区分     则称T为可辨别联合(一句话总结:同名、可辨别的简单类型的key)                                                                                                                   

3.类型断言as:

用于已知参数类型

什么是所有类型的联合?(所有类型不包括never/unknown/any/void)

答案:unknown

any为什么不是所有类型的联合?

用反证法可以证明

const f1 = (a:number | string) {
    a.toFixed(2) // error
    a.split(',') // error
    // 在未进行类型收窄前只能使用类型共有的方法
}

const f1 = (a:any) {
    a.toFixed()
    a.join()
    a.split(' ')
    // 可以使用任意类型的方法
}

TS中绝大部分规则对any不生效

unknown才是所有类型的联合

const f1 = (a:unknown) => {
    if(typeof a === 'string') {
        a
    }else if (a instanceof Date) {
        a
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值