映射具有未知深度的通用 TypeScript 接口

Posted

技术标签:

【中文标题】映射具有未知深度的通用 TypeScript 接口【英文标题】:Mapping a generic TypeScript interface with unknown depth 【发布时间】:2018-11-14 14:10:19 【问题描述】:

我有一个递归函数,它接受一个具有通用接口的对象。该函数遍历对象并创建一个具有几乎完全相同接口的新对象,除了端节点/叶子之外,它将它们转换为数字。该函数返回这个新对象,但我不知道如何给它正确的类型。

例子:

interface IOriginal

    prop1: string,
    prop2: number,
    prop3: 
        prop1: boolean,
        prop2: 
            prop1: number
        ,
        prop3: string
    


const input : IOriginal = 
    prop1: "somestring",
    prop2: 5,
    prop3: 
        prop1: true,
        prop2: 
            prop1: 2
        ,
        prop3: "otherstring"
    


function traverse<T>(obj: T)

    /* ... map the object ... */
    return mappedObj


const output = traverse(input)

输出的(映射对象的)接口应该是这样的

interface IOutput

    prop1: number,
    prop2: number,
    prop3: 
        prop1: number,
        prop2: 
            prop1: number
        ,
        prop3: number
    

对于映射类型,我似乎只能映射第一层深度,如果这有意义的话。

【问题讨论】:

【参考方案1】:

你可以使用条件类型来实现这个结果:

type LeafsToNumbers<T> = 
    T extends string | number | boolean  ? number :  // If primitive transform to number
     [ P in keyof T] : T[P] extends (infer U)[] ? LeafsToNumbers<U>[] : LeafsToNumbers<T[P]> ; // Otherwise recursively map, with a special case for arrays.

function traverse<T>(obj: T) : LeafsToNumbers<T>

    /* ... map the object ... */
    return null as any;

let a: IOriginal;
let o = traverse(a);
o.prop1 //number
o.prop3.prop1 // number

【讨论】:

我还不能投票给你的帖子,因为我没有所需的业力,但非常感谢你!完美运行。

以上是关于映射具有未知深度的通用 TypeScript 接口的主要内容,如果未能解决你的问题,请参考以下文章

具有通用方法的Typescript接口

Typescript - 具有通用类型函数的索引签名

您如何定义具有键字符串索引但具有特定类型的已知键的 TypeScript 接口?

优化 JSON 到 Typescript 映射

将具有一对多关系的 .Net Core 实体映射到 Angular 2 接口

在 TypeScript 中扩展参数化接口的通用接口