typescript使用泛型枚举类型方法在参数中返回枚举值

9lowa7mx  于 2023-06-24  发布在  TypeScript
关注(0)|答案(1)|浏览(175)

我需要返回一个包含枚举的所有值的列表(指定为参数或泛型)。如果用户有一个特定的角色,我只需要一些枚举值作为参数。
我考虑将这两个参数写成一个元组,因为它们要么都给定,要么没有。
我的第一次尝试看起来是这样的:

getItemsBasedOnRole<T extends enum>(...[role, items]?: [UserRole, T[]]) : string[]
{
    const allValues = Object.values(T);
    if (role && items) // tuple parameter exists
        if (this.securityService.getUser.role === role)
            return items;

    return allValues;
}

const result = getItemsBasedOnRole<MyEnum>([ClientRole], [MyEnum.Value1, MyEnum.Value3]);
// returns [MyEnum.Value1, MyEnum.Value3]

const result = getItemsBasedOnRole<MyEnum>();
// returns [MyEnum.Value1, MyEnum.Value2, MyEnum.Value3]

export enum MyEnum{
    Value1 = 'Value1',
    Value2 = 'Value2',
    Value3 = 'Value3',
}

问题在Typescript中:

  • T extends enum不存在。

解决方案:替换为T extends { [s: number]: string }

  • Object.values(T)需要一个值,T是一个类型。

考虑添加一个参数enumValue: T,但调用方法我无法传递MyEnum,它需要MyEnum.ValueX
找不到解决方案。

  • [role, items]?可选元组不存在。

找不到解决方案。
我的最后一次尝试,它显示了上面列表中的错误:

getItemsBasedOnRole<T extends { [s: number]: string }>(enumValue: T, ...[role, items]: [UserRole, T[]]): string[]

上面的问题与类型和函数定义有关,我只想返回一个动态列表。我愿意接受任何想法:多个函数,使用参数而不是泛型类型,等等。

juzqafwq

juzqafwq1#

我建议使用常量对象而不是enums,因为它们更可预测,更容易操作。我们需要应用constAssert来防止编译器扩大对象的类型,并确保对象是类型安全的,我们将使用satisfies操作符:

export const MyEnum = {
  Value1: 'Value1',
  Value2: 'Value2',
  Value3: 'Value3',
} as const satisfies Record<string, string>

由于我们的枚举是Record<string, string>,我们将把泛型参数的约束更改为相关的约束:

declare function getItemsBasedOnRole<T extends Record<string, string>>(obj: T, ...args:[something]) {}

为了得到整个对象的值,我们将使用indexed accessT[keyof T]将给予所有值的并集:

declare function getItemsBasedOnRole<T extends Record<string, string>>(obj: T, ...args: [role?: UserRole, values?: T[keyof T][]]): string[]

用途:

getItemsBasedOnRole(MyEnum, 'role', ['Value1', 'Value2'])

Playground

相关问题