nmsn / blog

记录日常遇到的问题,需要记录的笔记以及新学到的知识,会进行汇总和分类,自动更新 README,欢迎评论和补充,互相学习
36 stars 0 forks source link

交叉类型的类型守卫 #17

Open nmsn opened 2 years ago

nmsn commented 2 years ago

类型判断 typeof

处理一些基础类型的数据 string | number | bigint | boolean | symbol | undefined | object | function

type Val = string | number;

const getValType = (val: Val) => {
  if (typeof val === 'string') {
    return val.split('');
  }

  if (typeof val === 'number') {
    return val.toFixed();
  }
};

不能检测更复杂的数据类型,例如 array

也不适合对于对象的属性进行判断(常见的使用误区)

type Car = {
  id: number;
  car: string;
};

type Bike = {
  id: string;
  bike: string;
};

type Vehicle = Car | Bike;

const getVal = (val: Vehicle) => {
  if (typeof val.id === 'number') {
    return val.car;
  }
};

// 这种情况是不能够达到目的的,会报错
// Property 'car' does not exist on type 'Vehicle'.
// Property 'car' does not exist on type 'Bike'.ts(2339)

那你想要通过对应的唯一属性判断也是不行的

const getVal = (val: Vehicle) => {
  if (typeof val.id === 'number') {
    return val.car;
  }

  if (val.car) {
    return val.car;
  }
};

// 同样的报错
// Property 'car' does not exist on type 'Vehicle'.
// Property 'car' does not exist on type 'Bike'.ts(2339)

如果非要使用 typdof 来判断的的话,只能添加类似 type 的属性来区分

type Car = {
  type: 'car';
  id: number;
  car: string;
};

type Bike = {
  type: 'bike';
  id: string;
  bike: string;
};

type Vehicle = Car | Bike;

const getVal = (val: Vehicle) => {
  if (val.type === 'car') {
    return val.car;
  }
};

这样才能通过类型检查,其实就没有必要了

属性或方法判断 in

通过 in 方法来区分对象就方便的多

const getVal = (val: Vehicle) => {
  if ('car' in val) {
    return val.car;
  }
};

这样就可以直接使用 Car 下的属性(不仅仅是代码中的 car 属性)

实例判断 instanceof

用的不多,用于判断类的实例