如何使用可能未定义的键作为索引?TypeScript类型报错解决
解决TypeScript索引未定义键的类型错误
问题根源
你的代码里,obj的key2对应的对象没有field属性,当泛型T传入key2时,(typeof obj)[T]['field']试图用不存在的field键索引类型,触发了TypeScript的2536错误。
解决方案1:限制泛型仅支持带field的键
如果只需要支持带有field属性的键,可以先筛选出符合条件的键类型,再限制泛型T的范围,从源头避免非法索引:
const obj = { key1: { field: { foo: 1, bar: 2, }, }, key2: {} } // 筛选obj中对应值包含field属性的键类型 type KeysWithField = { [K in keyof typeof obj]: 'field' extends keyof typeof obj[K] ? K : never }[keyof typeof obj]; // 限制T只能是符合条件的键 type Foo<T extends KeysWithField> = { [key in keyof (typeof obj)[T]['field']]: string } // 合法使用:生成包含foo、bar的string类型对象 type Test1 = Foo<'key1'>; // 非法使用会直接报错:类型 '"key2"' 不满足约束 'KeysWithField' // type Test2 = Foo<'key2'>;
解决方案2:兼容无field的键,返回默认类型
如果需要支持所有键,当对应值没有field时返回空对象或其他默认类型,可以用条件类型做分支处理:
const obj = { key1: { field: { foo: 1, bar: 2, }, }, key2: {} } type Foo<T extends keyof typeof obj> = 'field' extends keyof (typeof obj)[T] ? { [key in keyof (typeof obj)[T]['field']]: string } : {}; // 无field时返回空对象类型 // 测试 type Test1 = Foo<'key1'>; // { foo: string; bar: string; } type Test2 = Foo<'key2'>; // {}
内容的提问来源于stack exchange,提问作者damjuve
相关产品推荐
相关产品推荐

