【问题标题】:type check in TypeScript (with inheritance)TypeScript 中的类型检查(带继承)
【发布时间】:2021-09-07 23:43:32
【问题描述】:

我在尝试检查 angular 类型时遇到问题。

export interface DynamicComponentConfig {
    name: string;
    component: Type<any>;
}

export class DynamicInputComponent extends DynamicComponentBase {
}
export class DynamicDatePickerComponent extends DynamicComponentBase {
}

export class DynamicComponentBase {
    @Input() group: FormGroup;
    @Input() form: FormGroupDirective;
}

当我创建一个持有引用类型(不是该类型的实例)的实例时

let conf: DynamicComponentConfig = {
    component: DynamicInputComponent,
    name: 'Surname'
};

并传递给负责动态创建我的组件的服务,我需要检查类型,但 instanceof 不起作用:

if (conf.component instanceof DynamicComponentBase) {
...
}

只有当我直接检查它所属的类型时它才有效,但我有几个组件都继承自 DynamicComponentBase:

if (conf.component === DynamicInputComponent || conf.component === DynamicDatePickerComponent || ...) {
...
}

检查 config.component.prototype 我得到 DynamicComponentBase {constructor: ƒ},但如果我检查 config.component.prototype === DynamicComponentBase 我得到 false

所以我正在寻找一种方法来检查它们是否从我的基本组件继承,知道吗?

【问题讨论】:

  • 这能回答你的问题吗? Interface type check with Typescript
  • @SeanVieira 不是真的,正如 vaira 所说,conf.component 持有一个 typeOf DynamicInputComponent,而不是一个实例,但 typeof conf.component 返回“function”

标签: typescript inheritance


【解决方案1】:

经过研究,我找到了一个解决方案检查原型,它实际上解决了我从一个基本组件(DynamicComponentBase)继承多个组件(DynamicInputComponent、DynamicDatePickerComponent)的问题,所以我不必检查组件类型是否是一种或其他子类类型,只需使用 Object.getPrototypeOf:

if (Object.getPrototypeOf(config.component) === DynamicComponentBase) {
    // returns true!! :)
}

if (config.component.prototype === DynamicComponentBase) {
    // returns false
}

我唯一的疑问是为什么第二个表达式返回 false

【讨论】:

    【解决方案2】:

    conf.component 持有typeOf DynamicInputComponent,而不是动态实例。

    class Bat {
    public name?: string;
    
    }
    
    let typeOfBat = Bat;
    let obj = new  Bat();
    
    console.log(typeOfBat === Bat); // true
    console.log(obj === Bat); // false
    console.log(typeOfBat instanceof Bat); // false
    console.log(obj instanceof Bat); // true
    

    编辑后 // 您的问题是以下行。

    组件:类型;

    这里你只允许any 类型,所以你必须检查基数是否为DynamicComponentBase,但如果你写它component: typeof DynamicComponentBase;,那么你不必担心,Typescipt 会检查它你。

    class DynamicComponentBase {
     group: string = '';
     form: number = 0;
    }
    
    
     interface DynamicComponentConfig {
        name: string;
        component: typeof DynamicComponentBase; // this will either DynamicComponentBase or its child refered 
    }
    
     class DynamicInputComponent extends DynamicComponentBase {
    }
     class DynamicDatePickerComponent extends DynamicComponentBase {
    }
    
     class NotDynamicComponent  {
    }
    
    
    let conf: DynamicComponentConfig = {
        component: DynamicInputComponent, 
        name: 'Surname'
    };
    
    /*
    let conf1: DynamicComponentConfig = {
        component: NotDynamicComponent, // will lead to error
        name: 'Surname'
    };
    */
    
    if(conf.component === DynamicInputComponent) 
    {
        console.log("DynamicInputComponent");
    }
    
    if(conf.component === DynamicDatePickerComponent)
    {
        console.log("DynamicDatePickerComponent");
    }
    
    if(conf.component === NotDynamicComponent) // can never be true
    {
        console.log("NotDynamicComponent");
    }
    

    【讨论】:

    • 好的,所以检查类型的唯一方法是我已经说过的那个(conf.component === DynamicInputComponent)??没有办法检查继承基类/接口?
    • 如果我检查控制台 config.component.prototype 我得到 DynamicComponentBase {constructor: ƒ},但如果我检查 config.component.prototype === DynamicComponentBase 我得到 false
    • @vaiara,这正是我不想做的:检查组件是否是一种类型,我将不得不编写近 10 个 if-then 语句。将 type 更改为 typeof DynamicComponentBase 也不是问题,至少在我的实现中,因为我的代码允许动态创建任何组件,即使它没有扩展 DynamicComponentBase,但这超出了我的问题范围。我仍然认为我自己的答案更适合我的问题。无论如何感谢您的宝贵时间!
    猜你喜欢
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    相关资源
    最近更新 更多