在TypeScript中合并枚举

在TypeScript中结合多个枚举的好方法是什么?我的第一个直觉会告诉我要执行以下操作,但这会导致易于出错的代码重复。

export enum Formats {
  Shirt = 'shirt',Fruit = 'fruit',}

export enum Shirt {
  Yellow = 'yellow',Orange = 'orange',}

export enum Fruit {
  Orange = 'orange',lemon = 'lemon',}

export enum Item {
    ShirtYellow = 'shirt:yellow',ShirtOrange = 'shirt:orange',FruitOrange = 'fruit:orange',Fruitlemon = 'fruit:lemon',}

用例示例。枚举用于描述四个不同的对话框窗口。衬衫对话框处理程序已定义两个黄色和橙色的对话框窗口。黄色衬衫对话框和橙色衬衫对话框差异很大,以致于无法使用相同类型的对话框。衬衫对话框处理程序不了解水果对话框。水果处理器类似但相反。还有一个全局对话框管理器,负责确保在任何给定时间仅打开一个对话框。全局窗口管理器包含一个代表打开对话框的变量。此变量存储在磁盘上,以在重新加载应用程序/页面时保留打开的对话框状态。

iCMS 回答:在TypeScript中合并枚举

玩了一段时间之后,我想到了以下内容。仍然存在重复,但是至少存在一些交叉检查可以帮助防止错误。这样做的主要问题是它很冗长,很容易忘记一种组合。

type Pair<A,B> = [A,B]
const pair = <A,B>(a: A,b: B): Pair<A,B> => [a,b]

type ShirtYellow = Pair<Formats.Shirt,Shirt.Yellow>
type ShirtOrange = Pair<Formats.Shirt,Shirt.Orange>
type FruitOrange = Pair<Formats.Fruit,Fruit.Orange>
type FruitLemon = Pair<Formats.Fruit,Fruit.Lemon>

const ShirtYellow: ShirtYellow = pair(Formats.Shirt,Shirt.Yellow)
const ShirtOrange: ShirtOrange = pair(Formats.Shirt,Shirt.Orange)
const FruitOrange: FruitOrange = pair(Formats.Fruit,Fruit.Orange)
const FruitLemon: FruitLemon = pair(Formats.Fruit,Fruit.Lemon)

export type Item = ShirtYellow | ShirtOrange | FruitOrange | FruitLemon 
export const Item = { ShirtYellow,ShirtOrange,FruitOrange,FruitLemon };

这是我的第二次尝试。这次是基于对象的解决方案。

type AbstractItem<I extends { kind: Formats,type: any }> = I

export type ShirtItem = AbstractItem<{kind: Formats.Shirt,type: Shirt}>
export type FruitItem = AbstractItem<{kind: Formats.Fruit,type: Fruit}>

export type Item = AbstractItem<ShirtItem | FruitItem>

export const isShirt = (i: Item): i is ShirtItem => i.kind === Formats.Shirt
export const isFruit = (i: Item): i is FruitItem => i.kind === Formats.Fruit

export const getShirt = (i: Item): Shirt|null => isShirt(i) ? i.type : null
export const getFruit = (i: Item): Fruit|null => isFruit(i) ? i.type : null
,

我认为我们不应该专注于枚举之类的原始值类型。适当的记录或课程可以做您想要的。使用TypeScript,您可以构建"discriminated unions",即可以用一个字段(“标记”)区分的一类类型:

export enum ShirtOptions {
  Yellow = 'yellow',Orange = 'orange',}

export enum FruitOptions {
  Orange = 'orange',Lemon = 'lemon',}

interface Shirt {
    kind: 'shirt';
    options: ShirtOptions;
}

interface Fruit {
    kind: 'fruit';
    options: FruitOptions; // Can have a different name
}

type Format = Shirt | Fruit;

function handler(f: Format) {
    switch (f.kind) {
        case "shirt": return doShirtStuff();
        case "fruit": return doFruitStuff();
    }
}

TypeScript会对switch语句进行详尽的检查,并告诉您是否无法处理所有情况(有关详细信息,请参见链接)。

本文链接:https://www.f2er.com/2115987.html

大家都在问