简体   繁体   English

如何在 TypeScript 中获取 Enum 的最小值/最大值

[英]How to get the min/max value of Enum in TypeScript

I have a const enum in TypeScript, something like below:我在 TypeScript 中有一个 const 枚举,如下所示:

const enum ControlId {
   ZoomIn = 600,
   ZoomOut,
   Close, 
   Open,
   ....
}

Given a number, I want to know if it is within the range of ControlId, which is [600, ?], so that I can know if it falls into the category of ControlId or not.给定一个数字,我想知道它是否在ControlId的范围内,即[600,?],这样我就可以知道它是否属于ControlId的范畴。 I am wondering if there is a way to do that.我想知道是否有办法做到这一点。 Thanks.谢谢。

I think you're saying you have a runtime value and you want to know if it's a valid member of ControlId (you've said you want a "range check," but numeric enums aren't necessarily contiguous).我认为您是在说您有一个运行时值,并且您想知道它是否是ControlId的有效成员(您说过您想要“范围检查”,但数字枚举不一定是连续的)。

A const enum has no runtime existence, so you can't write runtime code to validate a number to see if it's a valid member of a const enum . const enum不存在运行时,因此您不能编写运行时代码来验证数字以查看它是否是const enum的有效成员。

You can do it if the enum isn't const :如果enum不是const ,您可以这样做:

enum ControlId {
    ZoomIn = 600,
    ZoomOut,
    Close, 
    Open,
    // ....
}

function assertIsControlId(value: number): asserts value is ControlId {
    if (!(value in ControlId)) {
        throw new Error(`Invalid ControlId value ${value}`);
    }
}

There I've done it as a type assertion function, but that could be a type guard function instead, or just an inline expression.在那里,我将它作为一个类型断言函数来完成,但这可能是一个类型保护函数,或者只是一个内联表达式。 Basically, if the value is a number, and the value (when converted to string, implicitly by the in operator) is a valid property name for ControlId , it's a valid member of ControlId .基本上,如果该值是一个数字,并且该值(当转换为字符串时,由in运算符隐式转换)是ControlId ControlId有效成员。

If you really mean you want the min/max, even though the enum values are not guaranteed to be contiguous, you can do that like this:如果您真的想要最小/最大值,即使不能保证枚举值是连续的,您也可以这样做:

function getMinMaxOfEnum(e: object) {
    const values = Object.keys(e).map(k => k === "" ? NaN : +k).filter(k => !isNaN(k)).sort((k1, k2) => k1 - k2);
    return [values[0], values[values.length - 1]];
}

(There's probably some better type for e than object . And in modern environments, values[values.length - 1] could be values.at(-1) .) (对于e来说,可能有比object更好的类型。在现代环境中, values[values.length - 1]可能是values.at(-1) 。)

That gets all of the keys from the object you pass in, converts them to number if possible, removes the ones that didn't convert successfully (so now we have an array of enum values), sorts the resulting array, and returns the first and last elements of the array.从您传入的对象中获取所有键,如果可能,将它们转换为数字,删除未成功转换的键(所以现在我们有一个枚举值数组),对结果数组进行排序,并返回第一个和数组的最后一个元素。

Alternatively, use Math.min and Math.max instead of sorting:或者,使用Math.minMath.max代替排序:

function getMinMaxOfEnum(e: object) {
    const values = Object.keys(e).map(k => k === "" ? NaN : +k).filter(k => !isNaN(k));
    return [Math.min(...values), Math.max(...values)];
}

Playground link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM