打字稿总是 returns "object"
Typescript casting always returns "object"
假设我有两个接口,它们有两个相同的成员 ID 和名称:
export interface InterfaceA {
id: number;
name: string;
//some other members
}
export interface InterfaceB {
id: number;
name: string;
//some other members
}
我想收集两种类型的元素来填充一些组合框。
我需要每个元素的 ID、名称和类型,所以我做了以下 class
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”class 构造函数中得到“对象”,我不知道为什么会这样。
我可以通过使用一些枚举来实现我的目标,但我想知道为什么这个解决方案不起作用,以及如何实现这一目标。
我宁愿不对 InterfaceA 或 InterfaceB 进行任何更改。
您无法在运行时访问对象的 TypeScript 类型(在一般情况下)。 TypeScript 提供了一个 compile-time 类型系统。您正在使用的 typeof
是 JavaScript runtime typeof
,它总是 returns "object"
对象任何类型(以及 null
)。
你说过要将类型发送到后端,所以你肯定在运行时需要它。我至少可以看到两种方法:
您可以将接口定义为 品牌接口 以确保始终包括类型:
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
的参数的任何对象都必须具有带有字符串 [=18= 的 type
属性 ] 和 InterfaceB
类似。然后您的代码将使用 type
属性.
您可以将构造函数设为私有,并且只允许通过接口的 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
.
假设我有两个接口,它们有两个相同的成员 ID 和名称:
export interface InterfaceA {
id: number;
name: string;
//some other members
}
export interface InterfaceB {
id: number;
name: string;
//some other members
}
我想收集两种类型的元素来填充一些组合框。 我需要每个元素的 ID、名称和类型,所以我做了以下 class
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”class 构造函数中得到“对象”,我不知道为什么会这样。 我可以通过使用一些枚举来实现我的目标,但我想知道为什么这个解决方案不起作用,以及如何实现这一目标。 我宁愿不对 InterfaceA 或 InterfaceB 进行任何更改。
您无法在运行时访问对象的 TypeScript 类型(在一般情况下)。 TypeScript 提供了一个 compile-time 类型系统。您正在使用的 typeof
是 JavaScript runtime typeof
,它总是 returns "object"
对象任何类型(以及 null
)。
你说过要将类型发送到后端,所以你肯定在运行时需要它。我至少可以看到两种方法:
您可以将接口定义为 品牌接口 以确保始终包括类型:
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
的参数的任何对象都必须具有带有字符串 [=18= 的type
属性 ] 和InterfaceB
类似。然后您的代码将使用type
属性.您可以将构造函数设为私有,并且只允许通过接口的
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
.