Currently there is now way to declare that a value should be a literal. This can be useful for declaring constraints for type parameters, e. g. type Foo<T: ('foo' | 'bar' | 'baz') & $StringLiteral> means that you can't use 'foo' | 'bar' as a parameter, you should pick exactly one.
Hmm, interesting! The normal subtyping rules for unions should allow any subset of union members to be a subtype of the whole union. That is, A|B, B|C, and A|C are subtypes of A|B|C.
I can imagine that a $StringLiteral kind would be useful to describe any string with literal information, but even then I'd expect a union of string literals to be a subtype of that type. That is, "foo"|"bar" would be a subtype of $StringLiteral because each arm of the union is a subtype.
Can you share a bit more about your use case?
@samwgoldman
I was just playing with new $PropertyType at it turns that it only works if you pass a string literal directly, so there is no way to use it with generic functions.
There other option to make it work is to make $PropertyType<T, 'A' | 'B'> to be the same as $PropertyType<T, 'A'> | $PropertyType<T, 'B'>
This could further help with a more dynamic $PropertyType as I wrote in #2310
Another use case could be something like this:
const createAction = <T: string, P>(type: T): { type: T } => {
return ({ type })
}
I would like to constraint T to a string literal type (not only string literal value), so I would have to call it like this:
const action = createAction(('FOO' : 'FOO'))`
(action.type: 'BAR') // Error :)
But since I can call it without the specific cast
const action = createAction('FOO')
(action.type: 'BAR') // No Error will pop up here :(
This is really useful to extract data with utility types but is really easy to forget passing the cast.
Hopefully it makes sense :)
How to address it?
I second the need for this use case
@Zaggen's example allows for much more correct typing of Redux actions/payloads
Most helpful comment
Another use case could be something like this:
I would like to constraint T to a string literal type (not only string literal value), so I would have to call it like this:
But since I can call it without the specific cast
This is really useful to extract data with utility types but is really easy to forget passing the cast.
Hopefully it makes sense :)