如何获取深度嵌套对象中所有嵌套值的原始类型联合类型?
深度嵌套对象的原始类型递归推导方案
我需要实现一个类型工具,提取深度嵌套对象(包含嵌套对象数组)内部所有的原始类型(包括null)。举个例子,给定如下对象:
const Data = { a: { x: "foo", }, b: { x: [123, 45], y: [ { x: null, }, { x: Symbol(666) }, ], }, };
期望推导得到类型 string | number | null | symbol,也就是:
type foo = DERIVE<typeof Data> // foo = string | number | null | symbol
之前找到的递归类型实现有问题,无法正确处理所有场景:
type RecursiveValues<T> = { [Prop in keyof T]: (T[Prop] extends Array<any> ? RecursiveValues<T[Prop][number]> : T[Prop] extends object ? RecursiveValues<T[Prop]> : T[Prop]) }[keyof T] type TestValues = RecursiveValues<typeof Data>
正确实现方案
问题核心在于:null在TypeScript中会被判定为object类型,导致原代码把null当成对象递归处理,同时原逻辑没有优先处理数组和null的边界情况。
修正后的类型工具如下:
type DERIVE<T> = // 优先处理null,避免被object分支捕获 T extends null ? null : // 处理数组,递归提取元素类型 T extends Array<infer U> ? DERIVE<U> : // 处理对象,递归提取所有属性的类型 T extends object ? DERIVE<T[keyof T]> : // 原始类型直接返回 T;
测试验证
用示例对象测试:
type foo = DERIVE<typeof Data>; // 最终类型为 string | number | null | symbol,完全符合预期
逻辑说明
- 优先判断
null:因为TS的类型系统中null extends object为真,必须单独分支处理,否则会进入对象递归逻辑导致错误。 - 数组处理:通过
infer U提取数组元素的类型,递归处理元素类型,覆盖嵌套对象数组的场景。 - 对象处理:提取对象所有属性的联合类型,递归处理该联合类型,遍历所有嵌套属性。
- 原始类型返回:当处理到原始类型(string/number/symbol/boolean等)时,直接返回该类型,终止递归。
内容的提问来源于stack exchange,提问作者Obiwahn
相关产品推荐
相关产品推荐

