您问题中方法的问题在于,您试图根据仅在编译时可用的类型脚本类型信息来控制JavaScript运行时行为.
JavaScript运行时只看到engineProperties
object,并不知道您的任何类型脚本接口或类型,这就是instanceof
或typeof
不适用于这种情况的原因.您可以考虑以下几种方法:
1.使用类而不是接口或类型
JavaScript支持classes,因此TypeScript类信息将在编译后继续存在,并可用于JavaScript运行时.这意味着您可以使用instanceof
操作符:
class PetrolEngineProperties {
constructor(
public cylinders: number,
public capacity: number
) {}
}
class ElectricEngineProperties {
constructor(
public numberOfBatteries: number,
public batteryCellSize: number
) {}
}
type EngineProperties = PetrolEngineProperties | ElectricEngineProperties;
function initializeCarEngine(engineProperties: EngineProperties) {
if (engineProperties instanceof ElectricEngineProperties) {
console.log('Electric engine was started');
} else if (engineProperties instanceof PetrolEngineProperties) {
console.log('Petrol engine was started');
}
}
initializeCarEngine(new ElectricEngineProperties(2, 6));
2.使用区别对待的联合
将判别式属性添加到您的类型,并创建一个discriminated union:
interface PetrolEngineProperties {
kind: 'PETROL';
cylinders: number;
capacity: number;
}
interface ElectricEngineProperties {
kind: 'ELECTRIC';
numberOfBatteries: number;
batteryCellSize: number;
}
type EngineProperties = PetrolEngineProperties | ElectricEngineProperties;
function initializeCarEngine(engineProperties: EngineProperties) {
if (engineProperties.kind === 'ELECTRIC') {
console.log('Electric engine was started');
} else if (engineProperties.kind === 'PETROL') {
console.log('Petrol engine was started');
}
}
initializeCarEngine({
kind: 'PETROL',
cylinders: 8,
capacity: 2400
});
3.写类型谓词
如果您发现自己处于不能或不想向对象添加属性的情况,则可以创建type predicates以使TypeScrip编译器相信对象是基于其现有内容的特定类型:
interface PetrolEngineProperties {
cylinders: number;
capacity: number;
}
interface ElectricEngineProperties {
numberOfBatteries: number;
batteryCellSize: number;
}
type EngineProperties = PetrolEngineProperties | ElectricEngineProperties;
function initializeCarEngine(engineProperties: EngineProperties) {
if (isElectric(engineProperties)) {
console.log('Electric engine was started');
} else if (isPetrol(engineProperties)) {
console.log('Petrol engine was started');
}
}
function isElectric(engineProperties: EngineProperties)
: engineProperties is ElectricEngineProperties {
return 'numberOfBatteries' in engineProperties
&& 'batteryCellSize' in engineProperties;
}
function isPetrol(engineProperties: EngineProperties)
: engineProperties is PetrolEngineProperties {
return 'cylinders' in engineProperties
&& 'capacity' in engineProperties;
}
initializeCarEngine({
cylinders: 8,
capacity: 2400
});
还有其他可能的解决方案,但要记住的主要一点是,在TypeScrip中,大多数类型信息在编译时消失,您不能将其用作运行时决策的基础.