首页 > 解决方案 > 打字稿:带有枚举的通用函数

问题描述

我使用几个枚举作为全局参数。

enum color {
    'red' = 'red',
    'green' = 'green',
    'blue' = 'blue',
};
enum coverage {
    'none' = 'none',
    'text' = 'text',
    'background' = 'background',
};

我将所有枚举合并到一个 type myEnums

type myEnums = color | coverage;

现在我想检查和访问枚举的值。例如:

// Returns undefined if the argument value is not a color.
function getColor(value: string): color | undefined{
    if(value in color) return value as color;
    return undefined;
}

因为有几个枚举,我想创建一个通用函数来访问我的所有枚举。我尝试了以下方法:

function getParam<T extends myEnums>(value: string): T | undefined {
    if(value in T) return value as T;
    return undefined;
}

getParam<color>('red', color);        // => should return 'red'
getParam<coverage>('test', coverage); // => should return undefined

但是 Typescript 编译器说: 'T' 仅指一种类型,但在这里被用作值。.

所以我向list: T函数添加了一个参数,但 Typescript 假定该参数list具有类型string(而不是object)。 'in' 表达式的右侧不能是原语。

function getParam<T extends allEnums>(value: string, list: T): T | undefined {
    if(value in list) return value as T;
    return undefined;
}

那么如何使用T枚举来调用泛型函数呢?

标签: typescripttypescript-generics

解决方案


我认为关键是正确键入T,您必须告诉 TS, T 是“类枚举定义”对象。我四处寻找,发现这个,或多或少的工作

我的一个项目中有这样的东西:

export function parseEnum<E, K extends string>(
  enumDef: { [key in K]: E },
  str: string | undefined
): E | undefined {
  if (str && str in enumDef) {
    return enumDef[str as K] as E;
  }
  return undefined;
}

所以,这就是“普通枚举”的工作原理,你想使用它的“总和”枚举。

幸运的是,由于 JS&TS 中实现枚举的方式,您可以像这样合并枚举定义对象:

const myEnums = {...coverage, ...color }
// typeof myEnums = coverage | color;

它有效:

const x = parseEnum(myEnums, 'x');
// typeof x = coverage | color | undefined;

打字稿游乐场在这里


推荐阅读