Last updated: Feb 27, 2024
Reading timeยท2 min
To get the element type from an array type:
infer
declaration to infer the type of an
element in the array.true
branch of the conditional type.type ArrElement<ArrType> = ArrType extends readonly (infer ElementType)[] ? ElementType : never; const arr1 = ['a', 'b']; // ๐๏ธ type T1 = string type T1 = ArrElement<typeof arr1>; const arr2 = ['a', 1]; // ๐๏ธ type T2 = string | number type T2 = ArrElement<typeof arr2>;
The type alias takes the type of the array using a generic.
We used a conditional type in the example.
Conditional types are very similar to the ternary operator.
Here is an example of how conditional types work.
interface Person { name: string; } interface Employee extends Person { id: number; } // ๐๏ธ string type T3 = Employee extends Person ? string : number;
We used the infer keyword to have TypeScript fill in the type of the array element.
Here is an oversimplified version of how the conditional type in the original example works.
// ๐๏ธ type T10 = string type T10 = string[] extends string[] ? string : never;
And here is the original code sample.
type ArrElement<ArrType> = ArrType extends readonly (infer ElementType)[] ? ElementType : never; const arr1 = ['a', 'b']; // ๐๏ธ type T1 = string type T1 = ArrElement<typeof arr1>;
At the moment, there is nothing that prevents the type from getting passed a generic that is not an array.
You can use a type guard to make sure that the type alias is only used with an array.
type ArrElement<ArrType extends readonly unknown[]> = ArrType extends readonly (infer ElementType)[] ? ElementType : never; const str = 'hello'; // โ๏ธ Error: Type 'string' does not satisfy // the constraint 'readonly unknown[]'.ts(2344) type T1 = ArrElement<typeof str>;
Now the passed in generic can only be a type that extends unknown[]
, in other
words an array containing elements of any type.