In the example below (playground link), I expect Foo<[0, 1]>
and Bar<[0, 1]>
both resolve to 0[] | 1[]
because of the union distribution in conditional types. However, Foo<[0, 1]>
is actually (0 | 1)[]
and the compiler claims that the first @ts-expect-error
directive is unused.
type Foo<T extends ArrayLike<unknown>> = T[number] extends infer Elem
? Elem[]
: never;
type Bar<T extends ArrayLike<unknown>> = T[number] extends infer Elem
? Elem extends infer U
? U[]
: never
: never;
// @ts-expect-error
const foo: Foo<[0, 1]> = [0, 1];
// @ts-expect-error
const bar: Bar<[0, 1]> = [0, 1];
I consulted the documentation and found the following statement;
When conditional types act on a generic type, they become distributive when given a union type. (emphasis on "a generic type" mine)
The only reason I can think of is that Elem
is a generic type in the example but T[number]
itself is not. I suspect this results in the conditional type not being distributive with T[number]
, but am not sure if my guess is correct. Could someone explain this behavior?
Distribution happens only over naked type parameters, meaning a single type parameter without any other type operation applied to it.
T[number]
is not a naked type parameter, so no distribution. Elem
is a naked type parameter in the second type, so distribution occurs.