首页 > 解决方案 > 如何创建多种类型的集合并将它们与 Typescript 中的类型一起使用?

问题描述

我有 2 种自定义类型,Graphic并且Asset我希望将它们放在同一个数组中。我希望能够访问它们并访问它们的类型信息。

const trail: Array<Graphic | Asset> = [];

for (let index = 0; index < this.props.graphics.length; index++) {
    const graphic = this.props.graphics[index];

    trail.push(graphic);

    if (index <= this.assets.length - 1) trail.push(this.assets[index]);
}

// this doesn't work, .artist does not exist on type Graphic | Asset
if (typeof trail[0].artist != "undefined") {

}

我认为以下类型的方法可以工作,但我还没有找到方法。

enum TrailType {
   Graphic,
   Asset
}
interface Trail {
   type: TrailType
   element: Graphic | Asset
}

只有当类型共享至少一个属性时才可能这样做?

标签: javascripttypescript

解决方案


是的,您需要有某种方式来定义类型是什么。它被称为discrimanted union. 你可以在这里阅读https://medium.com/@ahsan.ayaz/understanding-discriminated-unions-in-typescript-1ccc0e053cf5#:~:text=The%20discriminant%20is%20a%20singleton,the%20discriminant% 20或%20the%20标签

在您的情况下,它将按以下方式显示。

interface GraphicTrail {
    type: TrailType.Graphic,
    element: Graphic
}

interface AssetTrail {
    type: TrailType.Asset,
    element: Asset
}

type Trail = GraphicTrail | AssetTrail

现在您可以if检查以验证您正在使用哪种类型,因此 Typescript 将能够缩小变量的类型。

另一种解决方案是type guard。例如。

function isGraphic(data: Graphic | Asset): data is Graphic {
    return Boolean(data.someFieldsThatExistsOnGraphicOnly); // Here any boolean expression that you fill confident with will work.
}

推荐阅读