Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

交叉类型的类型守卫 #17

Open
nmsn opened this issue Jul 1, 2022 · 0 comments
Open

交叉类型的类型守卫 #17

nmsn opened this issue Jul 1, 2022 · 0 comments

Comments

@nmsn
Copy link
Owner

nmsn commented Jul 1, 2022

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

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

@nmsn nmsn added the TypeScript label Jul 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant