【TypeScript】别滥用联合类型和交叉类型

213 阅读1分钟

记录工作中踩的一个坑,联合类型 |和交叉类型&是工作中常用的,但是今天才发现,步入一个误区。比如

type Student = {
  name: string;
  age: string;
  types: 'student';
  school: string;
  schoolAddress: string;
};

type Worker = {
  name: string;
  age: number;
  types: 'worker';
  company: string;
  companyAddress: string;
};

export type Person = Student | Worker;

// 我们常常这样用
const person:Person
const {name,age,type,school,schoolAddress,company,companyAddress} = person
export type Person = Student | Worker;
const person: Person ;

其结果非预期

image.png

image.png

几种方式可破此举

1、Discriminated Unions

这是我从官网看到,不知道中文咋翻译

看官网例子就能明白了

image.png

所以我上面的例子,就是在使用的时候加个判断

image.png

image.png

2、 用交叉类型 &

但是要改下types的类型

image.png

image.png

如果 Category有很多值呢,然后定义Student时候又不想写Category类型,只想写types: 'student怎么办

3、 交叉类型 & 和联合类型 | 一起使用

和上面颇为相似 ,但是这次是在组合的时候使用

image.png

image.png

注意

交叉的类型中含有相同属性名但属性类型不一样的情况,该属性会成为never类型

Student的types定义'stduent',Workder的types定义为worker, 会得出 never

image.png

Student的types定义null,Workder的types定义为number, 会得出 never

image.png

Student的types定义string[],Workder的types定义为number, 会得出正确的类型

image.png

所以问题来了,这是为啥,还有一个问题,如使用第一种方式的话,有没有什么办法做到定义Student的时候,有没有办法只定义 Category的student, 目前想到的是使用枚举