如何从字符串数组类型参数推断subset函数的返回类型?
解决TypeScript subset函数的返回类型推断问题
修正后的函数实现
function subset< T extends Record<string, unknown>, U extends readonly (keyof T)[] = readonly (keyof T)[] >( source: T, keys?: U, filter?: (key: keyof T, value: T[keyof T]) => boolean ): U extends undefined ? T : Pick<T, U[number]> { if (!keys?.length || !source) { return source as any; } return keys.reduce((o, k) => { const value = source[k]; if (!filter || filter(k, value)) { o[k] = value; } return o; }, {} as Pick<T, U[number]>); }
关键改动说明
泛型约束优化:
- 限制
T为字符串键的对象类型Record<string, unknown>,明确输入类型边界 - 将
U约束为readonly (keyof T)[],确保传入的keys只能是源对象T的键组成的数组;同时给U设置默认值,对应不传keys的场景
- 限制
返回类型精准推导:
- 利用条件类型
U extends undefined ? T : Pick<T, U[number]>实现分支类型:- 当未传入
keys时,返回原对象类型T - 当传入
keys时,通过Pick<T, U[number]>提取T中对应keys数组元素的键值对类型,完全匹配期望结果
- 当未传入
- 利用条件类型
类型安全强化:
- 修正
filter函数的参数类型,从string和any改为keyof T和T[keyof T],避免类型丢失 - 将
reduce的初始值断言从any改为Pick<T, U[number]>,保证累加过程的类型一致性
- 修正
验证调用场景
const obj = {name:'John',age:40, address:'xxxx'}; const sub1 = subset(obj,['name','age']); // 推断类型:{ name: string; age: number; } const sub2 = subset(obj,['age','address']) // 推断类型:{ age: number; address: string; } const sub3 = subset(obj) // 推断类型:{ name: string; age: number; address: string; }
内容的提问来源于stack exchange,提问作者Ahmed Albahrawy
相关产品推荐
相关产品推荐

