05-TypeScript-交叉类型-联合类型-类型保护

交叉类型

  • 格式: type1 & type2 & ...
  • 交叉类型是将多个类型合并为一个类型
    let mergeFn = (arg1: T, arg2: U): T & U => {
    let res = {} as T & U
    res = Object.assign(arg1, arg2)
    return res
     }

  let res = mergeFn({ name: 'cs' }, { age: 11 })
  console.log('res', res)

联合类型

  • 格式: type1 | type2 | ...
  • 联合类型是多个类型中的任意一个类型
  // 联合类型
  let value: string | number
  value = 'abc'
  value = 123
}

类型保护

  • 对于联合类型的变量,在使用时如何确切告诉编译器他是哪一种类型
  • 主要有类型断言和类型保护
 
  let getRandomValue = (): string | number => {
    let num = Math.random()
    return num >= 0.5 ? 'abc' : 123.3
  }
  // 无法得知res1返回值类型
  let res1 = getRandomValue()
  console.log('res1', res1)
  • 方式一
  • 虽然类型断言可以确切告诉编译器当前的变量是什么类型
  • 但是每一次使用的时候都需要手动告诉编译器, 这样比较麻烦
  if ((res1 as string).length) {
    console.log((res1 as string).length)
  } else {
    console.log((res1 as number).toFixed())
  }
  • 方式二
  • 定义一个类型保护函数, 这个函数的返回类型是布尔类型
  • 这个函数的返回值是, 传入的参数 + is 具体类型

  function isString(value: string | number): value is string {
    return typeof value === 'string'
  }
  if (isString(res1)) {
    console.log((res1 as string).length)
  } else {
    console.log((res1 as number).toFixed())
  }

  • 方式三
  • 使用 typeof 来实现类型保护
  • 如果使用 typeof 来实现类型保护, 那么只能使用 === 或者 !==
  • 如果使用typeof 来是实现类型保护, 那么只能保护 number/ string/ boolean/ symbol类型
  if (typeof res1 === 'string') {
    console.log((res1 as string).length)
  } else {
    console.log((res1 as number).toFixed())
  }

  • 可以通过typeof来是来实现类型保护以外, 我们可以使用 instance
  class Person {
    name: string = 'css'
  }

  class Animal {
    age: number = 12
  }

  let getRandomObject = (): Person | Animal => {
    let num = Math.random()
    return num >= 0.5 ? new Person() : new Animal()
  }

  let obj = getRandomObject()
  console.log('obj', obj)
  if (obj instanceof Person) {
    console.log(obj.name)
  } else {
    console.log(obj.age)
  }
}

你可能感兴趣的:(05-TypeScript-交叉类型-联合类型-类型保护)