TS语法六 高级类型(一)

TS中的高级类型:

  • 交叉类型
  • 联合类型
  • 类型保护
  • null和undefined
  • 类型别名
  • 可辨识联合
一 交叉类型

交叉类型(&):用于组合多个类型为一个类型,常用于对象类型

interface Employee {
  employeeID: number;
  age: number;
}
interface Manager {
  stockPlan: boolean;
}
type ManagementEmployee = Employee & Manager;
let newManager: ManagementEmployee = {
    employeeID: 12345,
    age: 34,
    stockPlan: true
};

const mergeFunc = <T, U>(arg1: T, arg2: U): T & U => {
    return Object.assign(arg1, arg2)
}

console.log(mergeFunc({a:'aaa'},{b:'bbb'}))   //{a: 'aaa', b: 'bbb'}
二 联合类型

联合类型使用|分隔每种类型

let multiType: number | boolean;
multiType = 20;         //* Valid
multiType = true;       //* Valid
multiType = "twenty";   //* Invalid
三 类型保护

1.类型断言as

interface Bird {
  fly: boolean;
  sing: () => {};
}

interface Dog {
  fly: boolean;
  bark: () => {};
}

//用类型断言的方式进行类型保护
function trainAnmial(animal: Dog | Bird) {
  if (animal.fly) {
    (animal as Bird).sing();
  } else {
    (animal as Dog).bark();
  }
}

2.typeof实现类型保护

function add(first: string | number, second: string | number) {
  if (typeof first === 'string' || typeof second === 'string') {
    return `${first}${second}`;
  }
  return first + second;
}

注意:如果使用typeof来实现类型保护, 那么只能保护number/string/boolean/symbol类型,不能用于null,同时也不能用于interface和type定义的类型,因为这些类型在运行时就不在了。
3.instanceof实现类型保护
instanceof用于校验类,类的类型信息会在运行时保留。

 class  A {
    name:string = "1"
}
class  C {
    name1:string ="222"
}
function AM(param:A |C) {
    if(param instanceof A){
        //可以使用A的属性和方法
    }
    if(param instanceof C){
        //可以使用C的属性和方法
    }
}

4.in语法实现类型保护
in操作符对对象上的属性是否存在进行安全检查。

interface Dog {
    name: string
    bark: () => void
}

interface Bird {
    name: string
    fly: () => void
}

function doSomething(args: Dog | Bird) {
    if ('bark' in args) {
        args.bark()
    } else {
        args.fly()
    }
}

5.=== 和 !==
使用===和!==判断字面量类型

type CheckState = 'yes' | 'no' | 'unknown'

function doSomething(args: CheckState) {
    if (args === 'yes') {
        console.log('check state is yes')
    } else if (args === 'no') {
        console.log('check state is no')
    } else {
        console.log('unknown check state')
    }
}
四 null和undefined

null和undefined默认情况下是所有类型的子类型,即可以赋值给任意类型。但是如果在tsconfig.js中设置strictNullChecks为true时,就不能赋值给除它们自身以及void之外的类型了。想要使用可以配合联合类型来实现,如:

let s2: string | null = 'hi'

如果设置了"strictNullChecks": true,可选参数会被自动加上 |undefined,如果想要去除的话可以使用以下几种方法:
1.可选链(?.)

interface User {
  name: string
  address?: {
    street: string
  }
}

function printStreet(user: User) {
  const streetInfo = user.address?.street
  if (streetInfo === undefined) {
    console.log('No street info')
  } else {
    console.log(streetInfo)
  }
}

let user: User = {
  name: 'O.O'
}

printStreet(user) // 'No street info'

2.空值合并(??)
它允许编写在处理null或undefined时有回退的表达式。

function printName(name: string | null | undefined) {
  console.log(`${name ?? '无名氏'}`)
}

printName(null) // '无名氏'
printName('O.O') // 'O.O'

3.空断言(!)
有时候忽略一个值为 null 或 undefined 的可能性是有意义的。一个简单的方法就是使用类型转换,但是 TypeScript 也提供了 ! 运算符作为方便的快捷方式。

function getValue(): string | undefined {
  return 'hello'
}

let value = getValue()

value.length // value 可能为 undefined
// 使用 ! 运算符
value!.length // 5
五 type类型别名
type stringType = string
let str:stringType = 'abc'

type PositionType<T> = {x:T, y:T}
const position1: PositionType<number> = {
    x: 1,
    y: 2
}

const position2: PositionType<string> = {
    x: 'left',
    y: 'top'
}

type Childs<T> = {
    current: T,
    child?: Childs<T>
}
const children:Childs<string> = {
    current: 'first',
    child: {
        current: 'second',
        child: {
            current: 'third'
        }
    }
}

//可辨识联合
interface Square {
    kind:'square',
    size: number
}

interface Rectangle {
    kind:'rectangle',
    height:number,
    width:number
}

interface Circle {
    kind: 'circle',
    radius: number
}

type Shape = Square | Rectangle | Circle

function assertNever(value: never):never {
    throw new Error('unexpected error: ' + value)
}

function getArea(s: Shape):number{
    switch(s.kind){
        case 'square': return s.size * s.size;break;
        case 'rectangle': return s.width * s.height;break;
        case 'circle': return Math.PI * s.radius ** 2;break;   // **是平方
        default: return assertNever(s)   // 处理一些异常情况
    }
}
//这个例子通过统一的kind变量判断类型
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值