如何用TypeScript泛型实现类型安全的按类型筛选组件数组方法?
TypeScript 类型安全的组件查找函数实现
一、基于预定义联合类型的实现
先看你给出的组件类型定义:
interface IBaseWidget { type: string; } interface IButton extends IBaseWidget { type: 'button'; title: string; } interface ICheckbox extends IBaseWidget { type: 'checkbox'; checked: boolean; } type IWidget = IButton | ICheckbox; type IWidgetType = IWidget['type'];
当前的findByType函数返回的是IWidget[],无法自动推导对应类型的数组。要实现类型安全的返回结果,可以通过泛型+Extract工具类型来实现:
function findByType<T extends IWidgetType>( widgets: IWidget[], type: T ): Extract<IWidget, { type: T }>[] { // TS无法自动识别filter后的精确类型,需要类型断言 return widgets.filter(x => x.type === type) as Extract<IWidget, { type: T }>[]; }
效果验证
const buttons = findByType([], 'button'); // 类型自动推导为 IButton[] const checkboxes = findByType([], 'checkbox'); // 类型自动推导为 ICheckbox[]
Extract<IWidget, { type: T }>的作用是从IWidget联合类型中,筛选出type属性等于T的成员类型,从而让函数返回对应类型的数组。
二、完全泛型的通用版本
如果不想预先定义IWidget这类联合类型,希望直接从输入数组的类型中提取变体,可以进一步优化泛型约束:
function findByType<T extends { type: string }, U extends T['type']>( widgets: T[], type: U ): Extract<T, { type: U }>[] { return widgets.filter(x => x.type === type) as Extract<T, { type: U }>[]; }
效果验证
const input: ({type: 'A'} | {type: 'B'} | {type: 'C'})[] = []; const result = findByType(input, 'B'); // 类型自动推导为 {type: 'B'}[]
这个版本中:
T代表输入数组的元素类型(必须包含type属性)U捕获传入的具体type值Extract<T, { type: U }>从T联合类型中筛选出匹配type: U的成员,确保返回数组的类型完全匹配目标类型。
内容的提问来源于stack exchange,提问作者panta82
相关产品推荐
相关产品推荐

