TypeScript泛型中T[k]为何被推断为string而非字面量"john"?
问题解答
你的推断是否正确?
不正确。默认情况下,TypeScript会对对象字面量的属性类型进行字面量拓宽:当你直接传递{name:"john"}这种对象字面量给泛型参数T时,TS会把属性值的字面量类型"john"自动拓宽为基础类型string,所以T[k]最终解析为string,而非你预期的字面量类型"john"。
如何让TS推断字面量类型?
有两种常见方式:
- 使用
const断言,强制TS保留字面量类型:
此时// 单个属性添加const断言 test({name:"john" as const}, {name:(functionParam)=>null}) // 或给整个对象添加const断言 test({name:"john"} as const, {name:(functionParam)=>null})functionParam会被正确推断为字面量类型"john"。 - 调整泛型定义,通过约束触发字面量类型保留逻辑:
这里利用let test = <T extends Readonly<Record<string, unknown>>>(x: T, c: {[k in keyof T]:(p:T[k])=>void})=>{ } test({name:"john"}, {name:(functionParam)=>null})Readonly约束,让TS优先推断字面量类型,效果类似const断言。
相关查阅内容
可查看TypeScript官方文档中的以下核心章节:
- 字面量类型拓宽(Literal Type Widening):讲解TS自动拓宽字面量类型的场景与规则
- const断言(Const Assertions):介绍强制保留字面量类型的断言方式
- 泛型类型推断(Generic Type Inference):了解泛型参数的推断逻辑与优先级
内容的提问来源于stack exchange,提问作者user20216722
相关产品推荐
相关产品推荐

