如何从联合类型数组按指定参数查找值并推断返回类型?
可辨识联合类型数组按类型查找的类型安全实现
你可以通过泛型+类型谓词+内置Extract工具类型实现通用的按类型查找函数,不需要手动写as类型断言,TS会根据传入的类型标签自动推断返回值的具体类型。
核心实现
/** * 从带type可辨识标签的联合类型数组中查找匹配类型的元素 * 自动根据传入的type参数推断返回的具体类型 */ function findByType<T extends { type: string }, K extends T['type']>( array: T[], type: K ): Extract<T, { type: K }> | undefined { return array.find((item): item is Extract<T, { type: K }> => item.type === type); }
实现说明
- 泛型
T约束为带有type字符串属性的对象类型,自动匹配传入数组的成员联合类型 - 泛型
K约束为联合类型所有type字段的取值集合,会根据你传入的第二个参数自动推导具体字面量类型 - 用内置工具类型
Extract<T, { type: K }>从联合类型T中筛选出type属性等于K的成员类型,作为匹配成功后的返回类型 - 给
find的回调函数添加类型谓词item is Extract<T, { type: K }>,帮助TS完成类型收窄,不需要额外类型断言 - 返回值自动带上
undefined,和数组原生find方法的行为保持一致,提醒你处理找不到元素的边界情况
使用示例
对应你给出的类型定义,使用时不需要额外标注类型,TS会自动推断结果类型:
type One = { type: 'one'; value: string; } type Two = { type: 'two'; value: string; } type Three = { type: 'three'; value: string; } type Union = One | Two | Three; const array: Union[] = [ { type: 'one', value: 'first' }, { type: 'two', value: 'second' }, { type: 'three', value: 'third' } ] // 自动推断为 One | undefined,无需as断言 const one = findByType(array, 'one'); if (one) { // 此处TS能识别one为One类型,可安全访问value属性 console.log(one.value); } // 自动推断为 Two | undefined const two = findByType(array, 'two'); // 自动推断为 Three | undefined const three = findByType(array, 'three');
这个实现是通用的,所有以
type作为可辨识标签的联合类型数组都可以直接复用。如果你的项目里可辨识标签用的是其他字段名(比如kind、tag),只需要把函数里的type字段替换成对应字段名即可。
内容的提问来源于stack exchange,提问作者Jiyong Hong
相关产品推荐
相关产品推荐

