TypeScript中的 | 分隔符、& 运算符、类型谓词is

一. | 分隔符

在 TypeScript 中联合类型(Union Types)表示取值可以为多种类型中的一种,联合类型使用 | 分隔每个类型。联合类型通常与 null 或 undefined 一起使用:

const sayHello = (name: string | undefined) => { /* ... */ };

以上示例中 name 的类型是 string | undefined 意味着可以将 string 或 undefined 的值传递给 sayHello 函数。

sayHello("semlinker");
sayHello(undefined);

此外,对于联合类型来说,你可能会遇到以下的用法:

let num: 1 | 2 = 1;
type EventNames = 'click' | 'scroll' | 'mousemove';

示例中的 1、2 或 ‘click’ 被称为字面量类型,用来约束取值只能是某几个值中的一个。

二. & 运算符

在 TypeScript 中交叉类型是将多个类型合并为一个类型。通过 & 运算符可以将现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

let point: Point = {
  x: 1,
  y: 1
}

在上面代码中我们先定义了 PartialPointX 类型,接着使用 & 运算符创建一个新的 Point 类型,表示一个含有 x 和 y 坐标的点,然后定义了一个 Point 类型的变量并初始化。

同名基础类型属性的合并

那么现在问题来了,假设在合并多个类型的过程中,刚好出现某些类型存在相同的成员,但对应的类型又不一致,比如:

interface X {
  c: string;
  d: string;
}

interface Y {
  c: number;
  e: string
}

type XY = X & Y;
type YX = Y & X;

let p: XY;
let q: YX;

为什么接口 X 和接口 Y 混入后,成员 c 的类型会变成 never 呢?这是因为混入后成员 c 的类型为 string & number,即成员 c 的类型既可以是 string 类型又可以是 number 类型。很明显这种类型是不存在的,所以混入后成员 c 的类型为 never。

三. 类型谓词(is关键字)

当使用联合类型时,我们必须尽量把当前值的类型收窄为当前值的实际类型,而类型保护就是实现类型收窄的一种手段。

类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。换句话说,类型保护可以保证一个字符串是一个字符串,尽管它的值也可以是一个数字。类型保护与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值。

目前主要有四种的方式来实现类型保护:

  1. in 关键字;
  2. typeof 关键字;
  3. instanceof 关键字;
  4. 自定义类型保护的类型谓词(type predicate)

因为前三种比较常见,现在主要来看自定义类型保护的类型谓词
举例

type Student = {
 type: string;
 name: string;
 classRoom: string;
};

type Teacher = {
 type: string;
 name: string;
 officeRoom: string;
};

type A = Student | Teacher;

const isTeacher = (params:A) => {
 return params.type === "teacher"
}

const fu = (params:A) => {
 if(isTeacher(params)) {
   console.log(params.officeRoom)
 }
}

会有如下报错
TypeScript中的 | 分隔符、& 运算符、类型谓词is_第1张图片
解决方法

const isTeacher = (params:A):params is Teacher => {
  return params.type === "teacher"
}

应用场景:
在TypeScript中,我们往往会定义一个联合类型,来解决一些业务中复杂数据的处理。
当某个元素的类型是联合类型,取值时,当所访问属性为联合类型的公共属性(即交叉属性时)
TypeScript判定无风险,可用。但我们使用不交叉的属性时候,TypeScript会报错,报错信息如上。

  1. 解决联合类型问题的方法
    (1) 将所有非交叉属性设置 为可选属性;
    (2) 使用断言(as);
    (3) 类型谓词(is)

你可能感兴趣的:(TypeScript,typescript,javascript,前端)