代码之家  ›  专栏  ›  技术社区  ›  Emmanuel

Typescript:如何将“typeof类”的映射转换为类实例的映射

  •  0
  • Emmanuel  · 技术社区  · 4 年前

    const obj: {
        AddRowOperation: typeof RowOperations.AddRowOperation;
        DeleteRowOperation: typeof RowOperations.DeleteRowOperation;
        FilterRowsOperation: typeof RowOperations.FilterRowsOperation;
        ... 25 more ...;
        ResetRowStatusOperation: typeof RowOperations.ResetRowStatusOperation;
    }
    

    我想将这个对象映射到每个类的实例。因此,类型应为:

    const obj: {
        AddRowOperation: RowOperations.AddRowOperation;
        DeleteRowOperation: RowOperations.DeleteRowOperation;
        FilterRowsOperation: RowOperations.FilterRowsOperation;
        ... 25 more ...;
        ResetRowStatusOperation: RowOperations.ResetRowStatusOperation;
    }
    

    我尝试了很多选择,但最终该类型总是以如下方式联合:

    const obj: {
        AddRowOperation: (RowOperations.AddRowOperation | RowOperations.DeleteRowOperation | ...);
        // etc...
    }
    

    我本以为这是一个简单的场景。动态实例化类而不是手动键入每个类会更好。

    type InstanceTypeProps<T extends Record<keyof T, new (...args: any) => any>> = { [K in keyof T]: InstanceType<T[K]> };
    
    class A {}
    class B {}
    class C {}
    
    const obj = { A, B, C }
    
    type mapOfInstances = InstanceTypeProps<typeof obj>
    

    Demo

    1 回复  |  直到 4 年前
        1
  •  1
  •   jcalz    4 年前

    mapped type 结束 typeof obj InstanceType<T> , a utility type 哪个使用 conditional type inference 翻身 construct signature type 转换为它构造的实例。让我们称之为映射类型 InstanceTypeProps<T>

    type InstanceTypeProps<T extends Record<keyof T, new (...args: any) => any>> =
        { [K in keyof T]: InstanceType<T[K]> };
    

    我们只是申请而已 InstanceType T[K] . 唯一的额外细节是我们必须 constrain T 每个属性都是构造签名的类型。看起来像 Record<keyof T, new (...args: any) => any> ,表示其关键点是我们想要的任何关键点的对象(这样说对关键点没有任何约束) T extends Record<keyof T, ...> )并且其值可分配给 new (...args:any) => any ,一个构造签名。

    让我们确保它工作正常:

    type MapOfInstances = InstanceTypeProps<typeof obj>;
    /* type MapOfInstances = {
        AddRowOperation: RowOperations.AddRowOperation;
        DeleteRowOperation: RowOperations.DeleteRowOperation;
        FilterRowsOperation: RowOperations.FilterRowsOperation;
        //... 25 more ...;
        ResetRowStatusOperation: RowOperations.ResetRowStatusOperation;
    } */
    

    看起来不错!

    Playground link to code

    推荐文章