Reputation: 863
The Code:
type _join<_symbols extends [any, ...string[]]> = {
[_key in _symbols as _key extends [any, ...infer rest] ? join<rest, '/'> : never]: _key[0];
};
The rest
value should be inferred to as string[]
, but is instead inferred as unknown[]
. Why is this? The output works as expected, so the logic should be sound. I'm assuming it's some quirk of TS's syntax I'm missing?
Upvotes: 1
Views: 54
Reputation: 23825
You are right in your assumption that the logic is sound here but are hitting a limitation of the infer
keyword.
The information from the constraint of _symbols
is not carried over to the inferred type rest
as described in #21937. Types inferred from a generic type with the infer
keyword often do not have any further information associated with them and appear as opaque generic types.
For this example, the inference of rest
is not fully opaque. Since the position of the inference is a variadic tuple type, it is assumed by the compiler that rest
must extend unknown[]
which is what you see in the error message.
I found this proposal which, if implemented at some point, could give the compiler the ability to also factor in the constraints when inferring types using infer
. For now, the need for this feature is limited as PR#48112 introduced a way to explicitly provide a constraint when using the infer
keyword.
type _join<_symbols extends [any, ...string[]]> = {
[_key in _symbols as _key extends [any, ...infer rest extends string[]]
? join<rest, '/'>
: never
]: _key[0];
};
This is looks to be somewhat redundant; but for the foreseeable future we will need it to solve these issues.
Upvotes: 2