Reputation: 37829
Take this simple example of a string enum:
enum Animal {
Dog = "Dog",
Cat = "Cat",
Sheep = 'Sheep'
}
const getNoise = (animal: Animal) => {
switch (animal) {
case Animal.Dog:
return 'woof';
case Animal.Cat:
return 'meow';
case Animal.Sheep:
return 'baa';
}
}
But let's say I want to make another function that processes an arbitrary string
, originating from untrusted user input. The string should be a valid Animal
, but it might contain typos, so we need to validate it at runtime.
Here's an example:
const getNoiseUntrusted = (animal: string) => {
if (!(animal in Animal)) {
throw new Error('Animal not recognised');
}
return getNoise(animal); // TypeScript error
}
The getNoise(animal)
call causes a TypeScript error:
Argument of type 'string' is not assignable to parameter of type 'Animal'.
How can I get TypeScript to cast this string to an Animal
?
Upvotes: 3
Views: 230
Reputation: 671
Casting with as
works:
const getNoiseUntrusted = (animal: string) => {
if (!(animal in Animal)) {
throw new Error('Animal not recognised');
}
return getNoise(animal as Animal);
}
You can also expand on the switch in your regular getter, since you'd be checking the input string against the value of the specific enums.
const getNoiseUntrustedSwitch = (animal: string) => {
switch (animal) {
case Animal.Dog:
return 'woof';
case Animal.Cat:
return 'meow';
case Animal.Sheep:
return 'baa';
default:
throw new Error('Animal not recognised');
}
}
And finally, to build on @Daniel's answer, you can also cast while accessing the enum:
const getNoiseUntrustedEnumAcess = (animal: string) => {
if (!(animal in Animal)) {
throw new Error('Animal not recognised');
}
return getNoise(Animal[animal as Animal]);
}
See on TypeScript Playground
Although note that this is case-sensitive, so you may need to modify user input slightly before checking whether or not it is part of the enum.
Upvotes: 1
Reputation: 1042
Animal["Dog"]
will return "Dog"
Animal["Puppy"]
will return undefined
const getNoiseUntrusted = (animal: string) => {
if(!Animal[animal]){
throw new Error('Animal not recognised');
}
}
Upvotes: 2