MST
星途 面试题库

面试题:TypeScript联合类型与交叉类型在复杂类型系统设计中的权衡

在一个大型前端项目中,涉及到组件的属性类型定义、数据接口返回类型等复杂类型系统设计。请结合实际场景,分析何时应优先选择联合类型,何时应优先选择交叉类型,以及如何通过类型别名、泛型等手段来优化类型系统,以提高代码的可维护性和可扩展性。
22.3万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

联合类型优先场景

  1. 属性多种可选类型:例如在一个按钮组件中,type属性既可以是'button',也可以是'submit''reset'。此时使用联合类型 type ButtonType = 'button' | 'submit' | 'reset';,表示该属性只能是这些特定值中的一个。
  2. 函数参数多种类型:假设一个工具函数 printValue,它既可以接收字符串也可以接收数字并打印。function printValue(value: string | number) { console.log(value); },这样该函数就具有更广泛的适用性。

交叉类型优先场景

  1. 对象合并特征:当你需要一个对象同时具备多个类型的所有属性时。比如有一个BaseUser类型表示基本用户信息,AdminUser表示管理员额外信息。要定义一个管理员用户类型,就可以使用交叉类型 type Admin = BaseUser & AdminUser;,这样Admin类型就拥有了BaseUserAdminUser的所有属性。
  2. 混合功能接口:假设有一个Draggable接口表示可拖拽功能,Resizable接口表示可缩放功能,对于一个既可以拖拽又可以缩放的组件,其类型可以定义为 type DraggableResizable = Draggable & Resizable;

通过类型别名优化

  1. 简化复杂类型:对于复杂的联合或交叉类型,使用类型别名可以使其更易读。例如type ComplexType = (string | number) & { flag: boolean };,之后在代码中使用ComplexType就可以代表这个复杂类型,提高代码的可维护性。
  2. 复用类型:当多个地方用到相同的复杂类型时,定义一个类型别名可以避免重复书写。比如在多个组件的属性定义中都需要string | number这种联合类型,定义type StringOrNumber = string | number;,然后在各个组件属性定义中使用StringOrNumber

通过泛型优化

  1. 提高组件复用性:以一个列表组件为例,假设这个列表组件可以展示不同类型的数据。使用泛型 interface ListProps<T> { data: T[]; },这样无论数据是string类型、number类型还是自定义对象类型,都可以复用这个列表组件,极大提高了代码的可扩展性。
  2. 约束函数参数和返回值关系:比如一个函数identity,它返回与传入参数相同类型的值。function identity<T>(arg: T): T { return arg; },通过泛型T约束了参数和返回值的类型一致性,使得代码更加灵活且类型安全。