Home > front end >  Why doesn't union distribution happen with T[number] where T is an ArrayLike?
Why doesn't union distribution happen with T[number] where T is an ArrayLike?

Time:02-01

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?

CodePudding user response:

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.

  •  Tags:  
  • Related