Reputation: 27
I am trying to understand Conditional Types introduced in TypeScript 2.8 and reading the below official documentation.
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html
In Distributive conditional types, there is an example
type BoxedValue<T> = { value: T };
type BoxedArray<T> = { array: T[] };
type Boxed<T> = T extends any[] ? BoxedArray<T[number]> : BoxedValue<T>;
type T20 = Boxed<string>; // BoxedValue<string>;
type T21 = Boxed<number[]>; // BoxedArray<number>;
type T22 = Boxed<string | number[]>; // BoxedValue<string> | BoxedArray<number>;
In the above example, i didn't understand the meaning of
T[number]
in
BoxedArray<T[number]>
Is it referring to the first element of the Array passed or what is happening here?
Can someone please help me explain this.
Thanks in advance.
Upvotes: 1
Views: 236
Reputation: 327994
It's a "lookup type" or "indexed access type". A[B]
is the type of the value you get when indexing into an object of type A
with a key of type B
. So T[number]
is what you get when you index into an object of type T
with a numeric key. Note that such a type will only compile if T
is known to have a numeric index signature... for example, if T
is an array type, then T[number]
is the type of the elements of the array.
Thus, T extends any[] ? BoxedArray<T[number]> : BoxedValue<T>
means "for each union member of T
: if it is an array type, produce a BoxedArray
of its element type; otherwise, produce a BoxedValue
of it, and join them all up in a single union", as the examples show.
Hope that helps; good luck!
Upvotes: 3
Reputation: 152870
That's (another) use of lookup types. Basically think of T[number]
as the type of any element accessible by any numeric index.
For a uniform array (every element has the same type) this is the same as doing T[0]
which returns the type of the first element.
However this is not always the case. That's because TypeScript also has the concept of tuples.
Tuple types allow you to express an array with a fixed number of elements whose types are known, but need not be the same.
Let's say we have this tuple:
type Tuple = [string, number, string];
The first element and the last will be of type string
, but the second one is a number
. Using a lookup type we can access the different indices:
Tuple[0] // -> string
Tuple[1] // -> number
Tuple[2] // -> string
So if we use number
in the lookup type we don't get the type of one single element, but a union of all possible types:
Tuple[number] // -> string | number
Upvotes: 3