typescript :带枚举的通用函数

标签 typescript typescript-generics

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

enum color {
    'red' = 'red',
    'green' = 'green',
    'blue' = 'blue',
};
enum coverage {
    'none' = 'none',
    'text' = 'text',
    'background' = 'background',
};
我将所有枚举合并到一个类型 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 调用通用函数?作为枚举?

最佳答案

enum是 TypeScript 中的一种特殊数据结构。
如果你想限制泛型,你需要使用 typeof Enum反而。
在您的示例中,您期望 typeof color | typeof coverage而不是 color|coverage .
因为最后一个是值的联合,不管第一个是枚举的联合。
考虑这个例子:

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

type myEnums = color | coverage;

const hasProperty = <Obj, Prop extends PropertyKey>(obj: Obj, prop: Prop)
    : obj is Obj & Record<Prop, unknown> =>
    Object.prototype.hasOwnProperty.call(obj, prop);



function getParam<Keys extends PropertyKey, Value, E extends Record<Keys, Value>, Key extends keyof E>(enm: E, key: Key): E[Key]
function getParam<Keys extends PropertyKey, Value, E extends Record<Keys, Value>, Key extends PropertyKey>(enm: E, key: Key): Value | undefined
function getParam<E extends typeof color | typeof coverage, Key extends keyof E>(enm: E, key: Key): E[Key]
function getParam<E extends typeof color | typeof coverage, Key extends string>(enm: E, key: Key): undefined | E
function getParam<E extends typeof color | typeof coverage | Record<string, unknown>, Key extends keyof E>(enm: E, key: Key): E[Key] | undefined {
    return hasProperty(enm, key) ? enm[key] : undefined
}

const y = getParam(color, 'red');        // => color.red
const x = getParam(coverage, 'undefined'); // => undefined
const x2 = getParam({}, 'undefined'); // => unknown

const higherOrder = (key: string) => getParam(color, key)

const z = higherOrder('red') // typeof color | undefined
Playground
请记住,我不确定您想如何处理高阶函数,所以我刚刚返回了 enum 的联合。和 undefined在最后一个例子中
至于这条线if(value in T) :T是一种类型,您不能将 is 视为运行时值。

关于 typescript :带枚举的通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69160507/

相关文章:

javascript - 无法从 Firebase 下载数据 - TypeError : undefined is not an object

javascript - 如何从 typescript 上的txt文件获取数据?

Typescript 将元组的类型元组转换为元组(扁平元组)

reactjs - 通用 Typescript 类型 + React hook

javascript - 如何在 Typescript 中定义依赖于字符串参数的函数参数类型?

c# - 将具有一对多关系的 .Net 核心实体映射到 Angular 2 接口(interface)

typescript - 在 Typescript 中扩展全局声明的类型

typescript - 如何从函数范围之外获取变量的类型?

typescript - 在 Typescript 中索引其他属性的属性

typescript - 创建一个接受对象但不接受数组的通用函数