How can I constrain generic parameter to be assignable to string?
I have a function with a generic parameter T
. I intend this generic parameter to be either a sum types of different constant strings, like "alpha"|"beta"
, or an enum with string values, like enum ExampleEnum { Alpha = "ALPHA", Beta = "BETA" }
. Either way, in runtime all the values will be strings and I should be able to use them wherever strings are used.
Here's the example function:
function chooseRandom<T>(inputs: T[], callback: (chosen: T) => void) {
const t = inputs[4]; // die roll, guaranteed to be random
acceptsOnlyString(t);
callback(t);
}
function acceptsOnlyString(input: string) {
console.log(input);
}
And of course, with this, I get an error when I call acceptsOnlyString
:
Type 'T' is not assignable to type 'string'
I included the callback function in this example to explain why I can't just use string
— the users of chooseRandom
function will want to specify a callback that only accepts T
and not any possible string.
How do I explain to typescript that T
should be constrained to types that are assignable to a string?
You can restrict what types are allowed for a generic with the extends
keyword:
function chooseRandom<T extends string>(inputs: T[], callback: (chosen: T) => void) {
const t = inputs[4]; // die roll, guaranteed to be random
acceptsOnlyString(t);
callback(t);
}
With this restriction, typescript knows it's safe to pass t
into acceptsOnlyString
Playground link