I recieve a number type = 3
and have to check if it exists in this enum:
export const MESSAGE_TYPE = {
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4,
};
The best way I found is by getting all Enum Values as an array and using indexOf on it. But the resulting code isn't very legible:
if( -1 < _.values( MESSAGE_TYPE ).indexOf( _.toInteger( type ) ) ) {
// do stuff ...
}
Is there a simpler way of doing this?
This question is related to
javascript
typescript
enums
TypeScript v3.7.3
export enum YourEnum {
enum1 = 'enum1',
enum2 = 'enum2',
enum3 = 'enum3',
}
const status = 'enumnumnum';
if (!(status in YourEnum)) {
throw new UnprocessableEntityResponse('Invalid enum val');
}
export enum UserLevel {
Staff = 0,
Leader,
Manager,
}
export enum Gender {
None = "none",
Male = "male",
Female = "female",
}
Difference result in log:
log(Object.keys(Gender))
=>
[ 'None', 'Male', 'Female' ]
log(Object.keys(UserLevel))
=>
[ '0', '1', '2', 'Staff', 'Leader', 'Manager' ]
The solution, we need to remove key as a number.
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;
}
}
Usage
// 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
}
For anyone who comes here looking to validate if a string is one of the values of an enum and type convert it, I wrote this function that returns the proper type and returns undefined
if the string is not in the enum.
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;
}
}
As an example:
enum StringEnum {
value1 = 'FirstValue',
value2 = 'SecondValue',
}
keepIfInEnum<StringEnum>('FirstValue', StringEnum) // 'FirstValue'
keepIfInEnum<StringEnum>('OtherValue', StringEnum) // undefined
I've found that whenever I need to check if a value exists in an enum, I don't really need an enum and that a type is a better solution. So my enum in my original answer becomes:
export type ValidColors =
| "red"
| "orange"
| "yellow"
| "green"
| "blue"
| "purple";
For clarity, I like to break the values
and includes
calls onto separate lines. Here's an example:
export enum ValidColors {
Red = "red",
Orange = "orange",
Yellow = "yellow",
Green = "green",
Blue = "blue",
Purple = "purple",
}
function isValidColor(color: string): boolean {
const options: string[] = Object.values(ButtonColors);
return options.includes(color);
}
enum ServicePlatform {
UPLAY = "uplay",
PSN = "psn",
XBL = "xbl"
}
becomes:
{ UPLAY: 'uplay', PSN: 'psn', XBL: 'xbl' }
so
ServicePlatform.UPLAY in ServicePlatform // false
SOLUTION:
ServicePlatform.UPLAY.toUpperCase() in ServicePlatform // true
According to sandersn the best way to do this would be:
Object.values(MESSAGE_TYPE).includes(type as MESSAGE_TYPE)
This works only on non-const, number-based enums. For const enums or enums of other types, see this answer above
If you are using TypeScript, you can use an actual enum. Then you can check it using in
.
export enum MESSAGE_TYPE {
INFO = 1,
SUCCESS = 2,
WARNING = 3,
ERROR = 4,
};
var type = 3;
if (type in MESSAGE_TYPE) {
}
This works because when you compile the above enum, it generates the below object:
{
'1': 'INFO',
'2': 'SUCCESS',
'3': 'WARNING',
'4': 'ERROR',
INFO: 1,
SUCCESS: 2,
WARNING: 3,
ERROR: 4
}
If you want to use the variable as enum, just add the function:
Enum EVehicle {
Car = 'car',
Bike = 'bike',
Truck = 'truck'
}
const getVehicleAsEnum = (vehicleStr:string) => vehicleStr === 'car' ? EVehicle.Car : vehicleStr === 'bike' ? EVehicle.Bike : vehicleStr === 'truck' ? EVehicle.Truck : undefined
And then test:
const vehicleEnum = getVecicleAsEnum(str)
if(vehicleEnum) {
// do something
}
Type assertion is un-avoidable. Following up on
enum Vehicle {
Car = 'car',
Bike = 'bike',
Truck = 'truck'
}
I found one alternative that wasn't mentioned so thought I'd share my fix for it:
const someString: Vehicle | string = 'car';
const inEnum = (Object.values(Vehicle) as string[]).includes(someString);
I find this more truthful because we usually come in typesafe(with a string) and want to compare it to the enum; it'd be a bit reckless to typecast it to any
(reason: never do this) or Vehicle
(reason: likely untruthful). Instead, typecasting the Object.values()
output to an array of strings is in-fact very much real.
There is a very simple and easy solution to your question:
var districtId = 210;
if (DistrictsEnum[districtId] != null) {
// Returns 'undefined' if the districtId not exists in the DistrictsEnum
model.handlingDistrictId = districtId;
}
Source: Stackoverflow.com