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

时间:2018-06-05 07:11:58

标签: typescript dictionary generics types

我有一个递归函数,它接受带有通用接口的对象。该函数遍历对象并创建一个具有几乎完全相同的接口的新对象,除了端节点/叶子,它将它们转换为数字。该函数返回此新对象,但我无法找到如何为此提供正确的类型。

示例:

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 个答案:

答案 0 :(得分: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