TypeScript类型条件链操作符失效,如何提取可选嵌套类型?
TypeScript嵌套可选对象的类型提取方案
类型层面不能用运行时的?.操作符,这就是你报错的原因——?.是JavaScript运行时语法,TypeScript类型系统不支持直接用它来做类型提取。可以用下面几种方法实现需求:
方法1:写个通用递归类型工具
用条件类型结合infer做递归解析,支持点分隔的路径字符串,能自动处理可选属性的undefined情况:
type a = { one?: { two?: { three: string } } }; type DeepPick<T, Path extends string> = Path extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? DeepPick<T[Key], Rest> : undefined : Path extends keyof T ? T[Path] : undefined; // 最终类型是 string | undefined type threeType = DeepPick<a, 'one.two.three'>;
这个工具会逐层解析路径,遇到可选属性或者不存在的属性时自动返回undefined,完全贴合原对象的类型结构。
方法2:逐层手动判断类型
如果不想写通用工具,也可以逐层处理每个可选属性,用条件类型提取目标类型:
type a = { one?: { two?: { three: string } } }; // 逐层判断,最终得到 string | undefined type threeType = a['one'] extends { two: infer T } ? T extends { three: infer U } ? U : undefined : undefined;
这种写法更直接,适合简单的嵌套结构,能清晰看到每一层的类型判断逻辑。
方法3:支持数组索引的进阶工具
如果需要处理更复杂的嵌套(比如带数组的结构),可以扩展通用工具,支持数组索引路径:
type a = { one?: { two?: { three: string; arr?: string[] } } }; type DeepGet<T, Path extends string> = T extends undefined | null ? undefined : Path extends `${infer K}.${infer Rest}` ? K extends keyof T ? DeepGet<T[K], Rest> : undefined : Path extends `${infer K}[${infer Index}]` ? K extends keyof T ? T[K] extends (infer U)[] ? U : undefined : undefined : Path extends keyof T ? T[Path] : undefined; // 提取嵌套对象属性:string | undefined type threeType = DeepGet<a, 'one.two.three'>; // 提取数组元素类型:string | undefined type arrItemType = DeepGet<a, 'one.two.arr[0]'>;
内容的提问来源于stack exchange,提问作者kiborgKiller
相关产品推荐
相关产品推荐

