如何正确访问TypeScript中嵌套类型T[K]['default']?
解决TypeScript中访问嵌套属性类型的错误
问题代码
现有如下定义:
const fieldDefinitions = { a: { id: "14", "default": "none" }, b: { id: "15", "default": 0 }, c: { id: "16", "default": 0 }, }; const setFields = <T extends typeof fieldDefinitions, K extends keyof T>(fieldValues: { fieldName: K, value: T[K]["default"] }[]) => { // 设置字段的逻辑 };
需求是让setFields函数仅接受与对应字段default值类型一致的value参数:
合法调用示例:
setFields([ { fieldName: "a", value: "somestring" }, { fieldName: "c", value: 123 }, ]);原因:
a的default为字符串类型,c的default为数字类型,传入值类型匹配。非法调用示例(应报错):
setFields([ { fieldName: "a", value: 123 }, { fieldName: "c", value: "somestring" }, ]);原因:
a传入数字类型不匹配字符串,c传入字符串类型不匹配数字。
当前代码中value: T[K]["default"]报错,提示:Type '"default"' cannot be used to index type 'T[K]'。
错误原因
泛型约束T extends typeof fieldDefinitions仅限定T是fieldDefinitions的子类型,但TypeScript无法推导T[K]必然包含default属性——虽然实际我们知道所有字段都有,但类型系统需要明确约束。
正确解决方案
方案1:直接使用固定类型(推荐)
由于fieldDefinitions是固定的,无需泛型参数T,直接复用它的类型即可:
const fieldDefinitions = { a: { id: "14", "default": "none" }, b: { id: "15", "default": 0 }, c: { id: "16", "default": 0 }, }; // 提取fieldDefinitions的类型 type FieldDefinitions = typeof fieldDefinitions; const setFields = <K extends keyof FieldDefinitions>( fieldValues: { fieldName: K; value: FieldDefinitions[K]["default"] }[] ) => { // 设置字段的逻辑 };
这样TypeScript能明确知道每个FieldDefinitions[K]都包含default属性,不会再报错,同时严格约束value类型与对应字段的default一致。
方案2:增强泛型约束(适合需要扩展的场景)
如果需要保留泛型以支持不同的字段定义结构,需明确约束T的每个属性都包含default:
const fieldDefinitions = { a: { id: "14", "default": "none" }, b: { id: "15", "default": 0 }, c: { id: "16", "default": 0 }, }; // 定义包含default属性的字段类型 type FieldWithDefault = { default: unknown }; const setFields = <T extends Record<string, FieldWithDefault>, K extends keyof T>( fieldValues: { fieldName: K; value: T[K]["default"] }[] ) => { // 设置字段的逻辑 };
通过T extends Record<string, FieldWithDefault>确保T的所有属性都有default,此时T[K]["default"]的访问就是合法的。
内容的提问来源于stack exchange,提问作者Maurice Döpke
相关产品推荐
相关产品推荐

