This question Check if value exists in enum in TypeScript has several answers that do not work for string enums (or some say they do but others don't). It's more work than it should be to sort through those answers so another question will help people sort this out in the future.
Let's say I have a query string value that must be a type of Vehicle. I have this enum:
export enum VehicleTypes {
Car = 'car',
Bike = 'bike',
Skateboard = 'skateboard',
}
How do I verify that a string is one of the values in that enum?
if (! [...some logic here]) return response.code(400).send(`invalid vehicle type ${vehicle}`);
CodePudding user response:
When a string enum is transpiled, it doesn't do the same reverse lookup stuff that a number enum does. This simplifies things to the point that you can get a list of valid strings in a string enum using Object.values()
, and test against that for a type guard.
Here's an example of a function that will create a custom typeguard function for a specified string enum:
enum myStrEnum {
values = 'are',
all = 'strings',
}
function isValueInStringEnum<E extends string>(strEnum: Record<string, E>) {
const enumValues = Object.values(strEnum) as string[];
return (value: string): value is E => enumValues.includes(value);
}
const isValueInMyStrEnum = isValueInStringEnum(myStrEnum);
console.log(isValueInMyStrEnum('are')); // true
console.log(isValueInMyStrEnum('not')); // false
The as string[]
type assertion is necessary so TypeScript won't complain about using Array.prototype.includes
to check if a string
exists in an E[]
array.
If you just need a type guard for a specific enum then you can skip the outer function part of this example and create a custom typeguard function directly.
CodePudding user response:
This is the one I used, credit to gqstav.
if (!(Object.values(VehicleTypes) as string[]).includes(vehicle))
return response.code(400).send(`invalid vehicle type ${vehicle}`);