面试题答案
一键面试联合类型优先场景
- 属性多种可选类型:例如在一个按钮组件中,
type
属性既可以是'button'
,也可以是'submit'
或'reset'
。此时使用联合类型type ButtonType = 'button' | 'submit' | 'reset';
,表示该属性只能是这些特定值中的一个。 - 函数参数多种类型:假设一个工具函数
printValue
,它既可以接收字符串也可以接收数字并打印。function printValue(value: string | number) { console.log(value); }
,这样该函数就具有更广泛的适用性。
交叉类型优先场景
- 对象合并特征:当你需要一个对象同时具备多个类型的所有属性时。比如有一个
BaseUser
类型表示基本用户信息,AdminUser
表示管理员额外信息。要定义一个管理员用户类型,就可以使用交叉类型type Admin = BaseUser & AdminUser;
,这样Admin
类型就拥有了BaseUser
和AdminUser
的所有属性。 - 混合功能接口:假设有一个
Draggable
接口表示可拖拽功能,Resizable
接口表示可缩放功能,对于一个既可以拖拽又可以缩放的组件,其类型可以定义为type DraggableResizable = Draggable & Resizable;
通过类型别名优化
- 简化复杂类型:对于复杂的联合或交叉类型,使用类型别名可以使其更易读。例如
type ComplexType = (string | number) & { flag: boolean };
,之后在代码中使用ComplexType
就可以代表这个复杂类型,提高代码的可维护性。 - 复用类型:当多个地方用到相同的复杂类型时,定义一个类型别名可以避免重复书写。比如在多个组件的属性定义中都需要
string | number
这种联合类型,定义type StringOrNumber = string | number;
,然后在各个组件属性定义中使用StringOrNumber
。
通过泛型优化
- 提高组件复用性:以一个列表组件为例,假设这个列表组件可以展示不同类型的数据。使用泛型
interface ListProps<T> { data: T[]; }
,这样无论数据是string
类型、number
类型还是自定义对象类型,都可以复用这个列表组件,极大提高了代码的可扩展性。 - 约束函数参数和返回值关系:比如一个函数
identity
,它返回与传入参数相同类型的值。function identity<T>(arg: T): T { return arg; }
,通过泛型T
约束了参数和返回值的类型一致性,使得代码更加灵活且类型安全。