Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Retrieve element type information from array type

Tags:

typescript

Say I have some array type T[], is it possible to extract the type T within another alias / interface? For example my (fake) ideal code would be as follows:

// for illustration only...  type ArrayElement<T[]> = T;  // then, ArrayElement<string[]> === string 

If no, are there general type theory reasons for not allowing such an operator? If no again, I might suggest it be added.

Thanks!

like image 651
Ben Southgate Avatar asked Dec 21 '16 00:12

Ben Southgate


People also ask

How do you check the type of an element in an array?

Checking array elements using the for loop First, initialize the result variable to true . Second, iterate over the elements of the numbers array and check whether each element is less than or equal zero. If it is the case, set the result variable to false and terminate the loop immediately using the break statement.

How can we retrieve an element from an array?

Retrieving the first and last elements in a simple array can most easily be done by using the ARRAY_FIRST and ARRAY_LAST functions. Retrieving the next or previous elements in a simple array can most easily be done by using the ARRAY_PRIOR and ARRAY_NEXT functions.

How do you define a type of array of objects in TypeScript?

To declare an array of objects in TypeScript, set the type of the variable to {}[] , e.g. const arr: { name: string; age: number }[] = [] . Once the type is set, the array can only contain objects that conform to the specified type, otherwise the type checker throws an error. Copied!

Should I use [] or array in TypeScript?

There is no difference at all. Type[] is the shorthand syntax for an array of Type . Array<Type> is the generic syntax. They are completely equivalent.


1 Answers

Update: based on @jerico's answer below

The following type alias will return the type of the elements in an array or tuple:

type ArrayElement<ArrayType extends readonly unknown[]> =    ArrayType extends readonly (infer ElementType)[] ? ElementType : never; 

So these examples would work:

type A = ArrayElement<string[]>; // string type B = ArrayElement<readonly string[]>; // string type C = ArrayElement<[string, number]>; // string | number type D = ArrayElement<["foo", "bar"]>; // "foo" | "bar" type E = ArrayElement<(P | (Q | R))[]>; // P | Q | R  type Error1 = ArrayElement<{ name: string }>;  //                         ^^^^^^^^^^^^^^^^ // Error: Type '{ name: string; }' does not satisfy the constraint 'readonly unknown[]'. 

Explanation

The type guard (the bit in the angle brackets) ArrayType extends readonly unknown[] says that we expect the type parameter ArrayType to be at least a readonly array (it also accepts a mutable array) so that we can look at its element type.

This prevents passing in a non-array value, as in the final example, which prevents ArrayElement ever returning never.

Note that readonly unknown[] is syntax added in TypeScript 3.4; for earlier versions use ReadonlyArray<unknown>.

On the right-hand side, the conditional expression asks the compiler to fill in the value of ElementType in the pattern readonly ElementType[] and return ElementType if it can, or never if it can't.

Since the type guard at the beginning means we will only ever be passed a value which matches this pattern, it's guaranteed always to match and never to return never.

Previous answer

type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType[number]; 
like image 163
Will Madden Avatar answered Oct 15 '22 20:10

Will Madden