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

def*_*ant 4 generics dictionary types typescript

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

例子:

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)
Run Code Online (Sandbox Code Playgroud)

和输出的(映射对象的)界面应该看起来像

interface IOutput
{
    prop1: number,
    prop2: number,
    prop3: {
        prop1: number,
        prop2: {
            prop1: number
        },
        prop3: number
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Tit*_*mir 6

您可以使用条件类型来实现此结果:

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
Run Code Online (Sandbox Code Playgroud)

  • 我还不能为你的帖子点赞,因为我没有所需的业力,但非常感谢你!完美运行。 (2认同)