在打字稿中映射对象类型

时间:2020-03-13 20:26:10

标签: javascript typescript generics

我正在寻找打字稿中一种“映射”对象类型的方法。

我输入以下内容:

interface Factory<T>{
     serialize: (val: T)=>void,
     deserialize: ()=>T,
}
interface MyDict{
     [key: string]: Factory<any>
}

function deserialize(dict: MyDict){
     let mapped = {};
     for(let k in dict){
          mapped[k] = dict[k].deserialize();
     }
     return mapped;
}

我想要的是正确确定地图的返回类型。

因此,当执行此操作时:

let mapped = map({
    foo: {deserialize: ()=>'hello world'}, 
    foo2: {deserialize: ()=>123}, 
    foo3: {deserialize: ()=>({foo4: 'foo4'})}
});

映射的应键入为{foo: string, foo2: number, foo3: {foo4: string}}

1 个答案:

答案 0 :(得分:2)

您可以使用映射类型来执行此操作。该函数还需要通用才能捕获参数的实际类型:

interface Factory<T>{
     serialize?: (val: T)=>void,
     deserialize: ()=>T,
}
interface MyDict{
     [key: string]: Factory<any>
}

type FactoryReturnType<T extends MyDict> = {
    [K in keyof T]: ReturnType<T[K]['deserialize']>
}

function deserialize<T extends MyDict>(dict: T){
     let mapped = {} as FactoryReturnType<T>;;
     for(let k in dict){
          mapped[k] = dict[k].deserialize();
     }
     return mapped;
}

let mapped = deserialize({
    foo: {deserialize: ()=>'hello world'}, 
    foo2: {deserialize: ()=>123}, 
    foo3: {deserialize: ()=>({foo4: 'foo4'})}
});

mapped.foo3.foo4

Playground Link