关于Typescript枚举类的讨论

99 阅读2分钟

背景

本人原是做后端应用开发,但是近期在构思一款项目,前端计划使用vue3+ts的技术栈。首先个人认为ts的枚举类对解决魔法值而言无疑是很好的一个解决方案。但是仍有很多不足的地方,这些不足主要体现在与后端枚举的数据结构不统一上。本人在开发时,常常会使用枚举做下拉菜单(select)的选项,亦或根据枚举类型来读取一些数据。单目前以本人的知识储备来看没发现ts较好的解决方案。话不多说上代码。

Java中的枚举

@Getter
@RequiredArgsConstructor
public enum ExamModeEnum {
    // 随机模式每次都会从适配的题目中选择相应数量题目
    RANDOM(RandomPaperFactoryImpl.class, "随机"),
    // 比赛模式每次都会从适配的题目中选择相应数量题目,单参与比赛的人会读到相同的一份题目
    GAME(GamePaperFactoryImpl.class, "比赛"),
    // 固定模式,则一旦生成则选择好题目
    FIX(FixPaperFactoryImpl.class, "固定"),
    ;
    //
    private final Class<? extends IPaperFactory> paperFactory;
    private final String name;
}

可以看到Java中的枚举可以附带一些特殊内容,本人用其来做工厂类的处理

public static IPaperFactory getInstance(ExamModeEnum configuration) {
    IPaperFactory iPaperFactory = SpringUtil.getBean(configuration.getPaperFactory());
    return iPaperFactory;
}

Ts中的处理

为了让TS也有类似的功能,目前没找到比较优雅的方法,因此也希望大家提意见,看如何优化。以下是本人目前的处理

// 定义枚举
const enum ColorScheme {
    DARK,
    LIGHT
}

// 枚举拓展
interface EnumExt<T> {
    // 枚举值部分
    get DARK(): T;

    get LIGHT(): T;

    // 参考Java 实现需要有的功能
    get length(): number;

    ext: any;

    _enum: T;

    getExt(key: T);

    values();
}

export const colorSchemeEnumExt = (function (): EnumExt<ColorScheme> {
    const ext = {};
    // 拓展属性
    ext[ColorScheme.DARK] = {
        name: "dark",
        chinese: "黑暗模式"
    };
    ext[ColorScheme.LIGHT] = {
        name: "light",
        chinese: "亮模式"
    };
    return {
        get DARK(): ColorScheme {
            return ColorScheme.DARK
        },

        get LIGHT(): ColorScheme {
            return ColorScheme.DARK
        },

        get length(): number {
            return ColorScheme.length
        },

        _enum: ColorScheme,

        ext,

        getExt(key: ColorScheme) {
            return this.ext[key];
        },
        values() {
            const result = [];
            for (let extKey in this.ext) {
                result.push(this.ext[extKey])
            }
            return result;
        }
    }

})()

const name = colorSchemeEnumExt.getExt(colorSchemeEnumExt.DARK).chinese; // => 黑暗模式