TypeScript中如何判断对象键是否存在于泛型类型中?
解决方案:泛型键的运行时判断问题
首先明确:TypeScript的泛型类型是编译时信息,编译完成后会被完全擦除,运行时根本无法直接获取keyof TOutput这类类型层面的内容。所以你没法直接在if语句里判断某个键是否属于泛型类型的键集合,必须把需要的键信息以运行时值的形式传入函数。
具体实现思路
修改函数,新增一个参数用来传递允许保留的键(也就是TOutput的键集合),这样运行时就能通过这个参数判断当前遍历的键是否需要保留。同时通过TypeScript的类型约束,保证传入的键确实属于TOutput的键,兼顾类型安全和运行时逻辑。
代码示例
const fn = <TSource extends Record<string, any>, TOutput extends Record<string, any>>( src: TSource, allowedKeys: Array<keyof TOutput> ): Partial<TOutput> => { const output = {} as Partial<TOutput>; for (const key in src) { const element = src[key]; // 运行时判断当前键是否在允许的列表中 if (allowedKeys.includes(key as keyof TOutput)) { output[key as keyof TOutput] = element as TOutput[keyof TOutput]; } } return output; };
代码说明
- 参数
allowedKeys:类型设为Array<keyof TOutput>,编译时会强制要求传入的键必须是TOutput的有效键,避免传入无关键。 - 类型断言:
key as keyof TOutput和element as TOutput[keyof TOutput]是为了让TypeScript确认类型的安全性,因为for...in遍历的key默认是string类型,需要断言为TOutput的键类型。 - 返回值类型:用
Partial<TOutput>表示返回的对象可能包含TOutput的部分键,符合过滤后的结果特征。
替代思路(局限性较大)
如果你不想额外传参数,也可以传入一个TOutput的空对象模板,通过Object.keys()获取它的键,但这种方式只对必填键有效,如果TOutput的键是可选的,Object.keys()拿不到这些可选键,所以不如直接传allowedKeys可靠:
const fn = <TSource extends Record<string, any>, TOutput extends Record<string, any>>( src: TSource, outputTemplate: TOutput ): Partial<TOutput> => { const allowedKeys = Object.keys(outputTemplate) as Array<keyof TOutput>; const output = {} as Partial<TOutput>; for (const key in src) { if (allowedKeys.includes(key as keyof TOutput)) { output[key as keyof TOutput] = src[key] as TOutput[keyof TOutput]; } } return output; };
内容的提问来源于stack exchange,提问作者minefield_tester
相关产品推荐
相关产品推荐

