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变量判断类型

猜你喜欢

转载自blog.csdn.net/LittleMoon_lyy/article/details/124218827