You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于数值枚举的Visitor模式:寻求TypeScript更优实现方案

用Visitor模式确保枚举新增值的全场景处理(TypeScript优化方案)

需求背景

我希望借助Visitor模式,确保新增枚举值时所有相关业务场景都能被完整处理,避免遗漏。现有枚举定义如下:

export enum ActionItemTypeEnum {
    AccountManager = 0,
    Affiliate = 4,
}

当前实现方式

目前我手动维护Visitor接口和访问函数,新增枚举值时需要手动更新接口和switch分支——虽然缺失分支会触发编译错误,但整体维护成本较高:

interface IActionItemTypeVisitor<T> {
    accountManager(value: ActionItemTypeEnum.AccountManager): T;
    affiliate(value: ActionItemTypeEnum.Affiliate): T;
}

// 缺失枚举分支时会触发编译错误
const visitActionItemType = <T>(value: ActionItemTypeEnum, visitor: IActionItemTypeVisitor<T>) => {
    // eslint-disable-next-line
    switch (value) {
        case ActionItemTypeEnum.None:
            return visitor.none(value);
        case ActionItemTypeEnum.AccountManager:
            return visitor.accountManager(value);
    }
};

// 示例:实现Visitor接口处理权限逻辑
const permission = visitActionItemType(this.type, new ActionItemPermissionVisitor())

我想知道有没有更地道的TypeScript解决方案,减少手动维护的工作量。


优化后的最终解决方案

通过TypeScript的映射类型和枚举的反向映射特性,可以实现枚举值与Visitor方法的自动关联,新增枚举值时只需实现对应的Visitor方法即可,无需手动修改访问函数:

1. 自动生成Visitor类型

利用keyof和Uncapitalize工具类型,根据枚举的键自动生成Visitor接口的方法签名:

export type IActionItemTypeVisitor<T> = {
    [K in keyof typeof ActionItemTypeEnum as Uncapitalize<K>]: (value: (typeof ActionItemTypeEnum)[K]) => T;
};

2. 通用访问函数

通过枚举的反向映射获取枚举键,自动转换为小驼峰方法名,调用对应的Visitor方法:

export const visitActionItemType = <T>(value: ActionItemTypeEnum, visitor: IActionItemTypeVisitor<T>): T => {
    const key: string = ActionItemTypeEnum[value]?.[0].toLowerCase() + ActionItemTypeEnum[value]?.substring(1);
    return visitor[key]?.(value);
};

3. Visitor实现示例

实现自动生成的Visitor类型,新增枚举值时只需添加对应方法即可:

export class ActionItemVisitor implements IActionItemTypeVisitor<string> {
    public accountManager(value: ActionItemTypeEnum.AccountManager): string {
        return 'AccountManager';
    }

    public affiliate(value: ActionItemTypeEnum.Affiliate): string {
        return 'Affiliate';
    }
}

// 使用示例
const result: string = visitActionItemType(ActionItemTypeEnum.AccountManager, new ActionItemVisitor());

内容的提问来源于stack exchange,提问作者kemsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:00:58