typescript不能不掌握的高级特性(一)

引言

在当前这个typescript火的一塌糊涂的时候,掌握typescript的一些高级用法,对咱们开发出高质量的代码尤其重要。接下来的一段时间,笔者将会采用实例的方式向你们讲述typescript的一些高级用法。本期要讲述的是typescript里面的交叉类型&。typescript

定义

官方对交叉类型的解析一如既往的官方!!!编辑器

交叉类型是将多个类型合并为一个类型。 这让咱们能够把现有的多种类型叠加到一块儿成为一种类型,它包含了所需的全部类型的特性。 例如, Person & Serializable & Loggable 同时是 Person 和 Serializable 和 Loggable。 就是说这个类型的对象同时拥有了这三种类型的成员。函数

举个栗子

iUserInfo 类型对象将拥有 iName 和 iBaseInfo 两个类型的全部成员。ui

interface iName {
  firstName: string;
  lastName: string;
}

interface iBaseInfo {
  sex: 'male' | 'female';
  age: number;
}

type iUserInfo = iName & iBaseInfo;
const user: iUserInfo = {
  firstName: 'Jack',
  lastName: 'Ma',
  sex: 'male',
  age: 40,
};
复制代码

类型成员冲突处理

当类型存在冲突的时候,成员之间会继续合并,好比:spa

interface iProps1 {
  size: string;
}
interface iProps2 {
  size: number;
}
type iProps = iProps1 & iProps2;
let props: iProps = {
  size: 'ddd',
};
复制代码

合并后 iProps 将以下:code

type iProps = {
  size: string & number;
};
复制代码

显然,string & number 这种类型是不存在的,因此等价于cdn

type iProps = {
  size: never;
};
复制代码

因此编辑器报红,就很容易解析了。对象

咱们这里定义了 never 类型,never 类型是什么呢?blog

never 类型

下面看官方文档的解析ip

never 类型表示的是那些永不存在的值的类型。 例如, never 类型是那些老是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也多是 never 类型,当它们被永不为真的类型保护所约束时。 never 类型是任何类型的子类型,也能够赋值给任何类型;然而,没有类型是 never 的子类型或能够赋值给 never 类型(除了 never 自己以外)。 即便 any 也不能够赋值给 never。

初步看来,貌似没有用!以前我也一度是这么认为的,其实它的做用仍是很大的! 举个栗子,当你有一个联合类型:

type AllType = 'a' | 'b';
复制代码

在 switch 当中判断 type,TS 是能够收窄类型的 (discriminated union):

function handleValue(val: AllType) {
  switch (val) {
    case 'a':
      // val 在这里收窄为 'a'
      break;
    case 'b':
      // val 在这里收窄为 'b'
      break;
    default:
      // val 在这里收窄为 never
      const exhaustiveCheck: never = val;
      break;
  }
}
复制代码

注意在 default 里面咱们把被收窄为 never 的 val 赋值给一个显式声明为 never 的变量。若是一切逻辑正确,那么这里应该可以编译经过。 可是假如后来有一天你修改了 AllType 的类型:

type AllType = 'a' | 'b' | 'c';
复制代码

若是忘记了在 handleValue 里面加上针对 'c' 的处理逻辑,这个时候在 default 里面 val 会被收窄为 'c',致使没法赋值给 never,产生一个错误。

因此经过这个办法,你能够确保 handleValue 老是穷尽了全部 AllType 的可能类型。

@Author: WaterMan

相关文章
相关标签/搜索