如何使用Reflection API在TypeScript中获取数组项类型?

时间:2022-06-12 21:38:39

I have the following little class in TypeScript, with some public fields decorated:

我在TypeScript中有以下小类,其中一些公共字段被装饰:

class Company {
    @dataMember
    public name: string;

    @dataMember
    public people: Person[];
}

class Person {
    // ...
}

By using reflect metadata, I can determine the types of Company properties name and people: they are the constructor functions String and Array, respectively, which is expected and logical.

通过使用反射元数据,我可以确定公司属性名称和人员的类型:它们分别是构造函数String和Array,它们是预期的和逻辑的。

My property decorator function:

我的属性装饰函数:

function decorate(target: Object, propertyKey: string | symbol): void {
    var reflectType = Reflect.getMetadata("design:type", target, propertyKey);
    // ...
}

But how could I determine the type (constructor function) of array elements? Is it even possible? In the above example, it should be (a reference to) Person.

但是我如何确定数组元素的类型(构造函数)?它甚至可能吗?在上面的例子中,它应该是(引用)Person。


Note: I need the type reference before instantiation, and because of this, it is impossible to dynamically determine the type using array items: there are no array items, there isn't even an Array instance.

注意:我需要在实例化之前使用类型引用,因此,使用数组项动态确定类型是不可能的:没有数组项,甚至没有Array实例。

1 个解决方案

#1


4  

I don't think this is possible as of now. If you see the generated js file, for array of anything, it creates metadata with type as Array without any information on type.

我不认为这是可能的。如果您看到生成的js文件,对于任何内容的数组,它会创建类型为Array的元数据,而不包含任何类型信息。

__decorate([
    dataMember_1.dataMember, 
    __metadata('design:type', Array)
], Company.prototype, "people", void 0);

For built-in types, one way I could think of solving this problem is to pass the type in the decorator itself and writing the custom logic in the decorator code.

对于内置类型,我可以想到解决这个问题的一种方法是在装饰器本身传递类型并在装饰器代码中编写自定义逻辑。

@dataMember(String)
myProp: Array<String>

For Custom objects, most of the time when the decorator call is fired, the module is not fully loaded. So, one way is to pass the class name and parse it later.

对于Custom对象,大多数情况下,当触发装饰器调用时,模块未完全加载。所以,一种方法是传递类名并稍后解析它。

@dataMember("People")
people: People[]

#1


4  

I don't think this is possible as of now. If you see the generated js file, for array of anything, it creates metadata with type as Array without any information on type.

我不认为这是可能的。如果您看到生成的js文件,对于任何内容的数组,它会创建类型为Array的元数据,而不包含任何类型信息。

__decorate([
    dataMember_1.dataMember, 
    __metadata('design:type', Array)
], Company.prototype, "people", void 0);

For built-in types, one way I could think of solving this problem is to pass the type in the decorator itself and writing the custom logic in the decorator code.

对于内置类型,我可以想到解决这个问题的一种方法是在装饰器本身传递类型并在装饰器代码中编写自定义逻辑。

@dataMember(String)
myProp: Array<String>

For Custom objects, most of the time when the decorator call is fired, the module is not fully loaded. So, one way is to pass the class name and parse it later.

对于Custom对象,大多数情况下,当触发装饰器调用时,模块未完全加载。所以,一种方法是传递类名并稍后解析它。

@dataMember("People")
people: People[]