使用TypeScript实现filter操作后保留返回值强类型
TypeScript 内置的 Array.filter 方法只会将返回值为**类型谓词(x is T 语法)**的回调函数用于返回值的类型收窄,你之前实现的 isString 虽然返回了布尔字面量类型,但不属于类型谓词,因此无法触发 filter 的类型推断。
方案1:直接编写对应场景的类型守卫
这是最贴合你当前需求的写法,代码如下:
const arr = [ { id: 1, value: "foobar" }, { id: 2, value: () => "hello world" } ] as const; // 定义类型守卫,返回值用 item is T 语法标记筛选后类型 function hasStringValue<T extends { value: unknown }>(item: T): item is T & { value: string } { return typeof item.value === 'string'; } // 直接传入filter回调 const reduced = arr.filter(hasStringValue); // 此时 reduced 的类型会被自动推断为:readonly [{ readonly id: 1; readonly value: "foobar" }]
方案2:封装通用的强类型工具,适配后续map/reduce扩展
如果需要复用强类型逻辑,可以封装通用的类型安全工具函数,后续新增map、reduce等操作也可以按照相同思路封装:
// 通用类型谓词定义 type TypePredicate<T, U extends T> = (item: T, index: number, array: readonly T[]) => item is U; // 强类型filter实现 function typedFilter<T, U extends T>(arr: readonly T[], predicate: TypePredicate<T, U>): U[] { return arr.filter(predicate) as U[]; } // 通用isString类型守卫 function isString<T>(val: T): val is T & string { return typeof val === 'string'; } // 调用示例 const reduced = typedFilter(arr, (item): item is typeof item & { value: string } => { return isString(item.value); });
内容的提问来源于stack exchange,提问作者ken
相关产品推荐
相关产品推荐

