如何为TypeScript的convert函数添加类型,实现返回值精准推断?
TypeScript类型推断优化需求
问题描述
给定以下TypeScript代码:
interface GenericType<G> = { objectKey: G }, const convert = (arg: {[key: string]: GenericType<any>}) => Object.fromEntries(Object.entries(arg).map(([key, value]) => [key, value.objectKey])) const converted = convert({ foo: {objectKey: "hello world"}, bar: {objectKey: false} }) // 预期返回 {foo: "hello world", bar: false}
当前TypeScript仅能推断出converted的类型为{foo: unknown, bar: unknown},需要为convert函数添加合适的类型定义,使TypeScript可以正确推断出converted的类型为{foo: string, bar: boolean}。
解决方案
要实现精准的类型推断,核心是通过泛型约束保留输入对象每个属性的具体类型信息,避免用any丢失类型上下文。
修正并优化后的代码
// 先修复原接口的语法错误(接口定义无需=,且结尾不能用逗号) interface GenericType<G> { objectKey: G; } // 泛型T捕获输入对象的完整类型结构 const convert = <T extends Record<string, GenericType<any>>>(arg: T) => { return Object.fromEntries( Object.entries(arg).map(([key, value]) => [key, value.objectKey]) ) as { [K in keyof T]: T[K]["objectKey"] }; }; const converted = convert({ foo: { objectKey: "hello world" }, bar: { objectKey: false } }); // 此时converted的类型将被正确推断为:{ foo: string; bar: boolean }
关键要点
- 泛型约束:
<T extends Record<string, GenericType<any>>>限定输入arg为字符串键的对象,且每个属性都是GenericType实例,同时保留每个属性的具体类型。 - 返回类型映射:
as { [K in keyof T]: T[K]["objectKey"] }通过类型映射,将返回对象的每个键对应类型设置为原对象属性中objectKey的类型,实现精准推断。 - 语法修正:原代码中接口定义的
=和多余逗号是语法错误,必须先修正才能正常编译。
简化版(无需显式接口)
如果仅针对当前场景,也可以去掉GenericType接口,直接泛型捕获属性结构:
const convert = <T extends Record<string, { objectKey: any }>>(arg: T) => { return Object.fromEntries( Object.entries(arg).map(([key, value]) => [key, value.objectKey]) ) as { [K in keyof T]: T[K]["objectKey"] }; }; const converted = convert({ foo: { objectKey: "hello world" }, bar: { objectKey: false } });
内容的提问来源于stack exchange,提问作者Michael.Lumley
相关产品推荐
相关产品推荐

