如何返回带泛型映射类型的对象?TypeScript类型报错排查
TypeScript泛型函数返回映射类型的类型不匹配问题
你定义的映射类型和泛型函数逻辑本身没问题,但TypeScript编译器在泛型场景下没法自动把动态键和泛型参数的具体类型关联起来,导致返回值类型推断错误。
问题复现
你的代码如下:
type FooOrBar = "foo" | "bar" type ObjectWithHi<T extends FooOrBar> = { [key in T]: 'hi'; } function getFooOrBar<T extends FooOrBar>(fooOrBar: T): ObjectWithHi<T> { return { [fooOrBar]: 'hi', } }
编译器报错:
Type '{ [x: string]: string; }' is not assignable to type 'ObjectWithHi<T>'.
原因分析
编译器处理泛型函数时,没法确定fooOrBar这个动态键的具体类型就是泛型T对应的字面量,它会默认把这个对象的索引类型推断为string,所以返回值被识别成了{ [x: string]: string; },和你期望的ObjectWithHi<T>结构不匹配。
解决方法
你可以用以下几种方式让编译器正确识别返回值类型:
1. 直接使用类型断言
明确告诉编译器返回的对象就是ObjectWithHi<T>类型:
function getFooOrBar<T extends FooOrBar>(fooOrBar: T): ObjectWithHi<T> { return { [fooOrBar]: 'hi', } as ObjectWithHi<T> }
2. 分步赋值+类型断言
先创建符合类型的空对象,再赋值,这样编译器能更好地追踪类型:
function getFooOrBar<T extends FooOrBar>(fooOrBar: T): ObjectWithHi<T> { const result = {} as ObjectWithHi<T>; result[fooOrBar] = 'hi'; return result; }
3. 结合Object.assign辅助推断
利用Object.assign的类型特性,帮助编译器识别键的具体类型:
function getFooOrBar<T extends FooOrBar>(fooOrBar: T): ObjectWithHi<T> { return Object.assign({}, { [fooOrBar]: 'hi' }) as ObjectWithHi<T>; }
以上方法都能解决类型不匹配的问题,你可以根据自己的编码习惯选择。
内容的提问来源于stack exchange,提问作者Volkan
相关产品推荐
相关产品推荐

