我收到一个数字类型= 3,必须检查它是否存在于这个enum:

export const MESSAGE_TYPE = {
    INFO: 1,
    SUCCESS: 2,
    WARNING: 3,
    ERROR: 4,
};

我发现最好的方法是将所有Enum值作为一个数组,并在其上使用indexOf。但结果代码不是很容易读懂:

if( -1 < _.values( MESSAGE_TYPE ).indexOf( _.toInteger( type ) ) ) {
    // do stuff ...
}

有更简单的方法吗?


当前回答

对于你的问题,有一个非常简单易行的解决方法:

var districtId = 210;

if (DistrictsEnum[districtId] != null) {

// Returns 'undefined' if the districtId not exists in the DistrictsEnum 
    model.handlingDistrictId = districtId;
}

其他回答

下面的函数返回另一个函数,该函数作为输入enum的类型谓词(假设它是字符串样式的enum)。

function constructEnumPredicate<RuntimeT extends string, EnumClass extends {[key: string]: RuntimeT}>(enumClass: EnumClass): (maybeEnum: string) => maybeEnum is EnumClass[keyof EnumClass] {
    const reverseMapping: {[key: string]: boolean} = {};

    for (const enumVal in enumClass) {
        const enumStr = enumClass[enumVal];
        reverseMapping[enumStr] = true;
    }

    function result(maybeEnum: any): maybeEnum is EnumClass[keyof EnumClass] {
        return !!reverseMapping[maybeEnum];
    }

    return result;
}

它可以在TypeScript 4.2.4中工作,但我还没有测试早期版本。

主要有趣的部分是EnumClass[keyof EnumClass]返回类型。当这样的类型是TypeScript中的enum时,它会返回enum的原始类型,其中EnumClass是运行时enum类的类型。

对于如何使用这个结构的例子,假设我们有以下枚举:

enum Direction {
    Left = "<-",
    Right = "->"
}

Direction既是一种类型,也是一个运行时对象。我们可以为Direction生成一个类型谓词,并像这样使用它:

const isDirection = constructEnumPredicate(Direction);
function coerceDirection(maybeDir: string): Direction {
    // Since we make a type predicate rather than just a normal predicate,
    // no explicit type casting is necessary!
    return isDirection(maybeDir) ? maybeDir : Direction.Left;
}
enum ServicePlatform {
    UPLAY = "uplay",
    PSN = "psn",
    XBL = "xbl"
}

就变成:

{ UPLAY: 'uplay', PSN: 'psn', XBL: 'xbl' }

so

ServicePlatform.UPLAY in ServicePlatform // false

解决方案:

ServicePlatform.UPLAY.toUpperCase() in ServicePlatform // true

对于你的问题,有一个非常简单易行的解决方法:

var districtId = 210;

if (DistrictsEnum[districtId] != null) {

// Returns 'undefined' if the districtId not exists in the DistrictsEnum 
    model.handlingDistrictId = districtId;
}

类型断言是不可避免的。跟进

enum Vehicle {
    Car = 'car',
    Bike = 'bike',
    Truck = 'truck'
}

我发现了一个没有被提及的替代方法,所以我想分享一下我的解决方法:

const someString: Vehicle | string = 'car';
const inEnum = (Object.values(Vehicle) as string[]).includes(someString);

我发现这更真实,因为我们通常是类型安全的(与字符串),并希望将其与enum进行比较;这将是有点鲁莽的类型转换为任何(原因:永远不要这样做)或车辆(原因:可能不真实)。相反,将Object.values()输出类型转换为字符串数组实际上非常真实。

export enum YourEnum {
   enum1 = 'enum1',
   enum2 = 'enum2',
   enum3 = 'enum3',
}

const status = 'enumnumnum';

if (!Object.values(YourEnum)?.includes(status)) {
     throw new UnprocessableEntityResponse('Invalid enum val');
}