I dont know if is possible implement this with TS.
Here is a playground, could be better to understand.
I have a default type groups
type DefaultTypes = 'group1' | 'group2'
And a interface Group
interface Group<N> {
type: DefaultTypes | N
label: string
}
And a function to registerGroups
function registerGroups <T>(group: Group<T>) {}
This way I can add more type groups to DefaultTypes, but if I call registerGroups({})
without generic type, TS don't return an error to a different group type.
Is there a way to make it works?
Thx
Typescript infers type parameters from the arguments you passed in. In this case if you don't specify a type parameter the compiler will infer it based on the value you assign to type
, so for this example:
registerGroups({
label: 'Group 4',
type: 'group4' // How make TS return an error here?
})
T
is inferred as group4
. This is the designed behavior and it is the way it should work. The best kind of generic function is the kind that does not require you to pass in the type parameters explicitly.
There is no build-in way to disable inference, there are some workarounds through, based on the idea we can confuse the compiler into giving up on inference at a certain argument site by using some conditional types. This is solution from jcalz is the one I usually use in such cases. Pair this with a default for T
of never
and you get the expected behavior. The default is needed because if TS has no place to infer T
from it defaults to unknown
, and unknown | N
is unknown
so anything is assignable. But if T
defaults to never
we get never | N
which simplifies to N
so only values of type N
will be assignable`:
type NoInfer<T> = [T][T extends any ? 0 : never];
function registerGroups <T = never>(group: Group<NoInfer<T>>) {}
// group4 is not in Types, but no error
registerGroups({
label: 'Group 4',
type: 'group4' // How make TS return an error here?
})