在不创建实例的情况下获取通用类型的元信息

时间:2019-12-03 07:59:50

标签: typescript typescript-generics

我有ProjectionMap类型的子类型,这些子类型具有一组属性,这些属性要么是ProjectionMap类型(它的任何子类型),要么是任何其他类型。例如:

class SimpleProjectionMap extends BaseProjectionMap {
    prop1: string;
    prop2: number;
    complexProp: AnyClassOrInterface;
}

class ComplexProjectionMap extends BaseProjectionMap {
    prop1: string;
    prop2: number;
    complexProp: AnyClassOrInterface;
    nestedProjectionMapProp: SimpleProjectMap[];
}

每个ProjectionMap实体都应能够将自己表示为以下形式的对象:

[entity.prop]: 1

或换句话说SimpleProjectionMap将变为:

{
    "prop1": 1;
    "prop2": 1;
    "complexProp": 1;
}

ComplexProjectionMap

{
    "prop1": 1;
    "prop2": 1;
    "complexProp": 1;
    "nestedProjectionMapProp.prop1": 1;
    "nestedProjectionMapProp.prop2": 1;
    "nestedProjectionMapProp.complexProp": 1;
}

具有ProjectionMap子类型的嵌套对象应该像上面的示例一样传播。

我基本上是在构建用于mongodb的投影对象,并且我想根据类型(在这种情况下为接口或类)动态生成对象。

现在,我有一个通用方法,该方法接受ProjectionMap类型作为通用参数,并且应该完全基于通用类型构造投影对象。该函数类似于:

async getItemsAsync<ProjectionMapType>(): Promise<ProjectionMapType[]> {
    // Generate projection object from ProjectionMapType and pass it to mongo for projection
}

现在,我无法使用ProjectionMap类型的接口,因为它们在编译后会消失。所以这给了我上课的机会。

此外,我想创建一个字典来缓存由ProjectionMap类型作为键,并将投影对象作为值组成的结果,因为考虑到对象是相同的,不应该为每个投影重建它们。现在,有两个问题:

async getItemsAsync<ProjectionMapType extends BaseProjectionMap>(): Promise<ProjectionMapType[]> {
    // Get type of ProjectionMapType to store it as a key in the caching map.
}
  1. 如果不创建实例,似乎无法获得ProjectionMapType的类型。基本上,typeof ProjectionMapType会导致编译错误。
  2. 如何获取类型的所有属性(无实例)以对其进行迭代并设置投影对象?

不创建实例就无法使其正常工作。我什至尝试使用静态方法生成投影对象,但仍无法在派生类型中使用该方法。

abstract class BaseProjectionMap {
    public static generateProjectionMapping(): object { 
        let projectionMap = new Map<string, number>();

        for (const key in this) {
            if (this.hasOwnProperty(key)) {
                const element = this[key];

                if (element instanceof BaseProjectionMap) {
                    // Handle nested ProjectionMapping objects                                                   
                }
                else {
                    projectionMap.set(key, 1);
                }
            }
        }

        return projectionMap; 
    }
}

以下代码在编译时返回错误:

async getItemsAsync<ProjectionMapType extends BaseProjectionMap>(marketIDs: string[]): Promise<ProjectionMapType[]> {
    const projectionMap = ProjectionMapType.generateProjectionMapping();

    // etc..
}

因此,作为总结: 1.是否可以在不创建实例的情况下获取Generic参数的类型? [基于阅读,我认为没有,但请确保。] 2.是否可以在不创建实例的情况下迭代类型的属性?

0 个答案:

没有答案