Issue
I have the following typescript code:
const myObject = {
foo: ['a', 'b', 'c']
}
type MyType = typeof myObject.foo extends [...infer Content] ? string : boolean
And MyType results in type string as expected.
But if I change the code like this:
...
type MyType = typeof myObject.foo extends [infer First, ...infer Tail] ? string : boolean
MyType now becomes boolean. Why?
Why does it extend in the first case but not in the latter?
Solution
First use case:
const myObject = {
foo: ['a', 'b', 'c']
}
type MyType1 = string[] extends [...infer Content] ? string : boolean
[...infer Content] - means that tuple might have 0 or 1 or more elements. No restriction at all.
Hence, since string[] is an array without explicit length (is not a tuple) you are getting string.
Second case
type MyType2 = string[] extends [infer First, ...infer Tail] ? string : boolean
[infer First, ...infer Tail] - mean that your tuple should have at least one element, because of First.
Because you are checking myObject.foo which is basically stirng[], TS is not allowed to make any assumptions about string[] length. string[] is a mutable array.
Try to make myObject immutable.
const myObject = {
foo: ['a', 'b', 'c']
} as const;
// string
type MyType1 = typeof myObject.foo extends readonly [...infer Content] ? string : boolean
//string
type MyType2 = typeof myObject.foo extends readonly [infer First, ...infer Tail] ? string : boolean
Now, both MyType's are strings.
SUMMARY
['a', 'b', 'c'] is infered as string[] because, like I said it is an array and not a tuple.
If you want it to make a tuple, you can use ['a', 'b', 'c'] as const.
Answered By - captain-yossarian
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.