【问题标题】:Typescript casting always returns "object"打字稿铸造总是返回“对象”
【发布时间】:2021-02-14 13:34:01
【问题描述】:

假设我有两个接口,它们有两个相同的成员 id 和 name:

export interface InterfaceA {
    id: number;
    name: string;
    //some other members
}

export interface InterfaceB {
    id: number;
    name: string;
    //some other members
}

我想收集两种类型的元素来填充一些组合框。 我需要每个元素的 id、名称和类型,所以我做了以下课程

export class AssignableDevice {
    id: number;
    name: string;
    type: string;

    constructor(device: InterfaceA | InterfaceB) {
        this.id = device.id;
        this.name = device.name;
        this.type = typeof device; //still returns "object"
    }
}

// in onInit method : 

ngOnInit() {
    super.ngOnInit();

    this.dataService.getInterfaceA().subscribe((data) => {
      data.forEach((element) => this.devices.push(new AssignableDevice(element as InterfaceA)));
    });

    this.dataService.getInterfaceB().subscribe((data) => {
      data.forEach((element) => this.devices.push(new AssignableDevice(element as InterfaceB)));
    })
}

但问题是我总是在“AssignableDevice”类构造函数中得到“对象”,我不知道为什么会这样。 我可以通过使用一些枚举来实现我的目标,但我想知道为什么这个解决方案不起作用,以及如何实现这一点。 我宁愿不对 InterfaceA 或 InterfaceB 进行任何更改。

【问题讨论】:

  • 你想用这个类型做什么?您还没有显示 this.type 在任何地方使用。如果我们知道您想用它做什么,我们就能更好地帮助您。
  • 我想将“type”与其他数据一起发送到后端,并在此基础上确定我应该在哪个表中插入记录。

标签: angular typescript casting type-conversion type-assertion


【解决方案1】:

您无法在运行时访问对象的 TypeScript 类型(一般情况下)。 TypeScript 提供了一个编译时类型系统。您使用的 typeof 是 JavaScript runtime typeof,对于任何类型的对象(以及 null),它总是返回 "object"

您已经说过要将类型发送到后端,因此您在运行时肯定需要它。我至少可以看到两种方法:

  1. 您可以将您的接口定义为品牌接口,以确保您始终包含以下类型:

    export interface InterfaceA {
        id: number;
        name: string;
        //some other members
        type: "InterfaceA"; // <== This is a _string literal type_ whose only valid value is the string "InterfaceA"
    }
    
    export interface InterfaceB {
        id: number;
        name: string;
        //some other members
        type: "InterfaceB"; // <=== String literal type
    }
    

    现在,您分配给InterfaceA 类型的变量、属性或参数的任何对象都必须具有带有字符串"InterfaceA"type 属性,InterfaceB 的字符串类似。然后您的代码将使用该 type 属性。

  2. 您可以将构造函数设为私有,并且只允许通过接口的createX 方法创建:

    export class AssignableDevice {
        id: number;
        name: string;
        type: string;
    
        private constructor(device: InterfaceA | InterfaceB, type: string) {
            this.id = device.id;
            this.name = device.name;
            this.type = type;
        }
    
        static createA(device: InterfaceA): AssignableDevice {
            return new AssignableDevice(device, "InterfaceA");
        }
    
        static createB(device: InterfaceB): AssignableDevice {
            return new AssignableDevice(device, "InterfaceB");
        }
    }
    

    现在您可以针对您拥有的对象类型使用适当的createX 方法。由于您在编写代码时做出了选择,TypeScript 可以检查您是否将正确类型的对象传递给 createX

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 2019-07-24
    • 2019-09-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2017-09-19
    相关资源
    最近更新 更多