TypeScript如何提取带索引签名类型中嵌套的复杂属性类型
TypeScript 提取嵌套对象属性类型实现方案
需求说明
需要提取预定义对象类型中嵌套的复杂类型,以便独立使用,原始类型定义如下:
// 'events?' 属性是待提取的大体量类型定义 type EventsCollection = { [k: string]: { name: string, events?: ComplexDefinition, desc: string }}
原有写法的问题
之前尝试的三类写法均未生效,核心问题是没有匹配实际的类型结构:
// 错误写法1:完全复制了整个EventsCollection结构,没有定位到嵌套的events属性 type Events = { [P in keyof EventsCollection ]: EventsCollection[P] } // 错误写法2:虽然取到了events属性,但保留了原属性的可选标记,得到的类型是ComplexDefinition | undefined type Events = { [P in keyof EventsCollection ]: EventsCollection[P]['events'] } // 错误写法3:构造了一个key和原类型一致、值为events类型的映射对象,不是events本身的类型定义 type key = 'events' type Events = { [P in keyof EventsCollection ]: Required<EventsCollection[P][key]> }
正确实现
根据实际使用场景二选一即可:
- 场景1:直接提取
events字段对应的类型本身(即ComplexDefinition,去掉可选的undefined)
由于EventsCollection是字符串索引签名类型,所有字符串key对应的值结构完全统一,不需要遍历key,直接通过索引访问取值即可:type ExtractedEvents = Required<EventsCollection[string]>['events'] // 最终得到的类型就是ComplexDefinition - 场景2:需要得到和原类型key一一对应、值为对应key下events类型的映射对象
遍历key时先通过Required去掉原属性的可选标记,再取events属性即可:type EventsMap = { [P in keyof EventsCollection]: Required<EventsCollection[P]>['events'] } // 最终得到的类型是 { [x: string]: ComplexDefinition }
补充:如果
EventsCollection是固定key的结构(而非通用字符串索引),上述写法同样适用,只需要把EventsCollection[string]替换成对应具体key的访问即可。
内容的提问来源于stack exchange,提问作者scramjet
相关产品推荐
相关产品推荐

