我收到一个数字类型= 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 ...
}

有更简单的方法吗?


当前回答

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

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()输出类型转换为字符串数组实际上非常真实。

其他回答

根据sandersn的说法,最好的方法是:

Object.values(MESSAGE_TYPE).includes(type as MESSAGE_TYPE)

对于任何来这里验证字符串是否是enum值之一并对其进行类型转换的人来说,我写了这个函数,它返回正确的类型,如果字符串不在enum中则返回undefined。

function keepIfInEnum<T>(
  value: string,
  enumObject: { [key: string]: T }
) {
  if (Object.values(enumObject).includes((value as unknown) as T)) {
    return (value as unknown) as T;
  } else {
    return undefined;
  }
}

举个例子:

enum StringEnum {
  value1 = 'FirstValue',
  value2 = 'SecondValue',
}
keepIfInEnum<StringEnum>('FirstValue', StringEnum)  // 'FirstValue'
keepIfInEnum<StringEnum>('OtherValue', StringEnum)  // undefined

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

var districtId = 210;

if (DistrictsEnum[districtId] != null) {

// Returns 'undefined' if the districtId not exists in the DistrictsEnum 
    model.handlingDistrictId = districtId;
}
export enum UserLevel {
  Staff = 0,
  Leader,
  Manager,
}

export enum Gender {
  None = "none",
  Male = "male",
  Female = "female",
}

log中的差异结果:

log(Object.keys(Gender))
=>
[ 'None', 'Male', 'Female' ]

log(Object.keys(UserLevel))
=>
[ '0', '1', '2', 'Staff', 'Leader', 'Manager' ]

解决方案,我们需要删除键作为一个数字。

export class Util {
  static existValueInEnum(type: any, value: any): boolean {
    return Object.keys(type).filter(k => isNaN(Number(k))).filter(k => type[k] === value).length > 0;
  }
}

使用

// For string value
if (!Util.existValueInEnum(Gender, "XYZ")) {
  //todo
}

//For number value, remember cast to Number using Number(val)
if (!Util.existValueInEnum(UserLevel, 0)) {
  //todo
}

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

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()输出类型转换为字符串数组实际上非常真实。