简体   繁体   English

有没有办法在打字稿中获取属性的声明类型而不是赋值的类型

[英]Is there a way to get the declared type of a property rather than the type of the assigned value in typescript

I am attempting to create a generic model class in typescript that can be extended by child models for the purposes of creating an automatic HTTP data to model processing method in the super class.我试图在打字稿中创建一个通用模型类,它可以由子模型扩展,目的是创建一个自动 HTTP 数据来模拟超类中的处理方法。

A basic child model might be as such:一个基本的子模型可能是这样的:

export class User extends Model {

    private username: string = null;

    constructor () {
        super ();
        this.processJson ();
    }
}

With our parent Model class doing something like:使用我们的父 Model 类执行以下操作:

export class Model {

    constructor () {
    }

    public processJson<T> () {

        _.forEach (Object.keys (this), (key: string) => {
            console.log (`processing key: ${key}`);
            console.log (typeof this[key]);
        })
   }
}

The plan is to use the processJson method a single entry point to take inbound JSON data and process it into our child models according to their definition.计划是使用processJson方法作为单个入口点来获取入站 JSON 数据并根据其定义将其处理到我们的子模型中。

The issue here is that I can't seem to get the declared type that is defined in the child model, in the provided example the typeof this[key] will return object since it infers the type of the assigned value in this example null .这里的问题是我似乎无法获得在子模型中定义的声明类型,在提供的示例中, typeof this[key]将返回object因为它推断出此示例中分配值的类型null

My plan is to use this for more complex cases where we might have more complex objects or different types that have special processing and perform it all in a centralized place within our parent Model class.我的计划是将它用于更复杂的情况,在这些情况下,我们可能有更复杂的对象或具有特殊处理的不同类型,并在父 Model 类中的一个集中位置执行所有这些。

My question is as such, how can I knowing the properties of the child model, get the declared type of our example of username as string NOT object ?我的问题是这样的,我如何知道子模型的属性,将我们的username示例的声明类型作为string NOT object

Is this a limitation of the underlying JavaScript that is generated?这是生成的底层 JavaScript 的限制吗? or am I misunderstanding how declared class properties work in Typescript?还是我误解了 Typescript 中声明的类属性是如何工作的?

I know that when declaring a property as:我知道在声明财产时:

private username: string = '';

It will give me the correct type, but I don't want to initialize values until they are assigned by the JSON data as in some cases null might be a valid value.它会给我正确的类型,但我不想初始化值,直到它们被 JSON 数据分配,因为在某些情况下null可能是一个有效值。

Your code snippet assumes you need the typescript's type information at run time.您的代码片段假定您在运行时需要打字稿的类型信息。 However, at run time all types are erased by typescript compiler.但是,在运行时所有类型都被打字稿编译器擦除。 It only emits plain javascript without type annotations.它只发出没有类型注释的纯 javascript。

I believe your best bet would be to create a decorator and decorate every property of a model with it - like this:我相信你最好的选择是创建一个装饰器并用它装饰模型的每个属性 - 像这样:

class User extends Model {
  @ModelField private username: string;
}

Also make sure you enable emitDecoratorMetadata compiler option ( https://www.typescriptlang.org/docs/handbook/decorators.html#metadata )还要确保您启用了emitDecoratorMetadata编译器选项( https://www.typescriptlang.org/docs/handbook/decorators.html#metadata

It should allow you to read the type of a decorated property via reflect-metadata (eg as suggested in this answer: How to get type data in TypeScript decorator? ).它应该允许您通过反射元数据读取装饰属性的类型(例如,如本答案中所建议: 如何在 TypeScript 装饰器中获取类型数据? )。

You can check declared type using typeof , === strict comparison and instanceof您可以使用typeof===严格比较和instanceof检查声明的类型

enter image description here在此处输入图片说明

Sample code:示例代码:

class Circle {
    public kind: string = '';
    public radius: number = 0;
}

let objCircle: Circle;

objCircle = { 
    kind: 'circle1', 
    radius: 123 
} as Circle;

console.log(typeof objCircle.kind === 'string')  // true
console.log(typeof objCircle.radius === 'number') // true
console.log(objCircle instanceof Object) // true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM