请看下面的打字代码:

interface PetrolEngineProperties {
    cylinders: number;
    capacity: number;
}

interface ElectricEngineProperties {
    numberOfBatteries: number;
    batteryCellSize: number;
}

function initializeCarEngine(engineProperties: PetrolEngineProperties | ElectricEngineProperties) {
    if (engineProperties instanceof ElectricEngineProperties) {
        // Do something with Electric Engine properties
    } else if (engineProperties instanceof PetrolEngineProperties) {
        // Do something with Petrol engine properties
        console.log('Petrol engine was started');
    }
}

有没有一种更惯用的方法来编写initializeCarEngine()API,也许是通过避免isElectric布尔值,除了知道强制转换类型之外,这似乎是多余的?我试图简单地传入engineProperties并使用instanceoftypeof进行类型判断,但不起作用.

我是打印界的新手,所以任何帮助都是感激的.谢谢!

推荐答案

您问题中方法的问题在于,您试图根据仅在编译时可用的类型脚本类型信息来控制JavaScript运行时行为.

JavaScript运行时只看到engineProperties object,并不知道您的任何类型脚本接口或类型,这就是instanceoftypeof不适用于这种情况的原因.您可以考虑以下几种方法:

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中,大多数类型信息在编译时消失,您不能将其用作运行时决策的基础.

Typescript相关问答推荐

类型脚本:类型是通用的,只能索引以供阅读.(2862)"

我们过go 不能从TypeScript中的联合中同时访问所有属性?

动态调用类型化函数

带switch 的函数的返回类型的类型缩小

如果字符串文字类型是泛型类型,则用反引号将该类型括起来会中断

为什么有条件渲染会导致material 自动完成中出现奇怪的动画?

如何使用类型谓词将类型限制为不可赋值的类型?

为什么我的查询钩子返回的结果与浏览器的网络选项卡中看到的结果不同?

以Angular 执行其他组件的函数

如何在React组件中指定forwardRef是可选的?

在抽象类属性定义中扩展泛型类型

如何在try 运行独立的文字脚本Angular 项目时修复Visual Studio中的MODULE_NOT_FOUND

设置不允许相同类型的多个参数的线性规则

重写返回任何

如何键入对象转换器

我如何键入它,以便具有字符串或数字构造函数的数组可以作为字符串或数字键入s或n

将对象数组传递给 Typescript 中的导入函数

使用嵌套属性和动态执行时,Typescript 给出交集而不是并集

在Typescript 中,是否有一种方法来定义一个类型,其中该类型是字符串子集的所有可能组合?

使用react+ts通过props传递数据