TypeScript中如何为含动态键的函数正确定义返回类型?
解决TypeScript函数返回类型无法正确推断字面量的问题
你的函数当前无法将数组元素推断为具体字面量类型,导致返回类型的索引签名是宽泛的string而非期望的字面量联合类型。以下是修复方案:
最优解决方案(TypeScript 5.0+)
使用const类型参数让TypeScript自动保留传入对象的字面量类型细节,无需手动添加断言:
function test<const T extends Record<string, readonly string[]>>( fieldsMap: T ): { [K in keyof T]: { [E in T[K][number]]: string | number }[] } { console.log(fieldsMap); return {} as any; // 实际实现时替换为业务逻辑 }
调用方式(无需显式指定泛型)
const result = test({ INFO: ['A', 'B', 'C'], OTHER: ['X', 'Y', 'Z'], });
此时result的推断类型完全符合预期:
type ExpectedResult = { INFO: { [p in 'A' | 'B' | 'C']: string | number }[], OTHER: { [p in 'X' | 'Y' | 'Z']: string | number }[] };
访问不存在的属性会直接触发编译错误:
result.INFO.map((I) => I.WORKING); // 编译报错:类型上不存在属性"WORKING"
兼容旧版本TypeScript方案(<5.0)
如果无法升级TypeScript版本,可在调用时添加as const断言,同时调整泛型约束:
function test<T extends Record<string, readonly string[]>>( fieldsMap: T ): { [K in keyof T]: { [E in T[K][number]]: string | number }[] } { console.log(fieldsMap); return {} as any; } // 调用时添加as const断言 const result = test({ INFO: ['A', 'B', 'C'], OTHER: ['X', 'Y', 'Z'], } as const);
问题根源说明
原代码中T extends { [key in K]: string[] }的约束会让TypeScript将数组元素推断为宽泛的string类型,而非具体的字面量值。通过const类型参数或as const断言,TypeScript会保留传入对象的完整字面量类型信息,从而让T[K][number]正确解析为数组元素的字面量联合类型。
内容的提问来源于stack exchange,提问作者Jeremy-F
相关产品推荐
相关产品推荐

