如何将TypeScript函数返回类型声明为递归数组所有层级a属性的字面量对象?
如何用TypeScript提取嵌套数组所有层级的
a属性作为对象键? 现有如下TypeScript代码,它只能提取数组第一层元素的a属性作为返回对象的键:
interface Item { a: string c?: Array<Item> } function g<const T extends Item>(p: Array<T>) { return {} as {[K in T as K['a']]: any} } // r的类型是 {a0: any, a1: any} const r = g([ { a: 'a0', c: [ { a: 'ac0' } ] }, { a: 'a1' } ])
实际需求是提取**所有层级(包括递归子级)**的a属性,期望返回对象的类型包含所有嵌套元素的a值作为键,比如:
interface Item { a: string c?: Array<Item> } function g1<T>(input: T) { return {} // 需要补充类型断言 } // 期望r1的类型是 {a0: any, ac0: any, a1: any} const r1 = g1([ { a: 'a0', c: [ { a: 'ac0' } ] }, { a: 'a1' } ])
可行性与实现方案
这在TypeScript中完全可行,核心是通过递归类型工具遍历嵌套结构,提取所有层级的a属性值。
完整实现代码
interface Item { a: string c?: Array<Item> } // 递归类型:提取所有层级的a属性值 type ExtractAllA<T> = T extends { a: infer A } ? A extends string ? A | (T extends { c: infer C } ? ExtractAllA<C> : never) : never : T extends Array<infer U> ? ExtractAllA<U> : never; // 改造后的函数,通过泛型捕获输入的字面量类型,再用递归类型生成键 function g1<const T>(input: T) { return {} as { [K in ExtractAllA<T>]: any }; } // 测试:r1的类型为 {a0: any, ac0: any, a1: any} const r1 = g1([ { a: 'a0', c: [ { a: 'ac0' } ] }, { a: 'a1' } ])
代码解释
ExtractAllA<T>递归类型:- 先判断
T是否包含a属性:如果是,提取a的类型A,同时检查T是否有c属性,递归提取c数组内所有元素的a值。 - 如果
T是数组类型,就递归处理数组的元素类型U,展开数组后提取单个元素的a值。 - 最终得到所有层级
a属性值的联合类型。
- 先判断
g1函数:- 使用
const泛型T,让TypeScript保留输入对象的字面量类型(比如'a0'、'ac0'这类具体字符串,而非宽泛的string)。 - 通过类型断言
as { [K in ExtractAllA<T>]: any },将返回对象的键设置为所有层级的a值联合类型。
- 使用
内容的提问来源于stack exchange,提问作者powerfulH
相关产品推荐
相关产品推荐

