12

I'm using TS 3.4.5 with the const assertion. How can I retrieve the type of the elements of the declared constant array variable?

export type GetArrayElementType<T extends Array<any>> = T extends (infer U)[] ? U : never;

export const MyConstArray = [
  'item1',
  'item2',
  'item3',
] as const;

export type MyConstArrayItem = GetArrayElementType<typeof MyConstArray>;

I'd like to have as output:

export type MyConstArrayItem = "item1" | "item2" | "item3"

I'm not totally sure how to extract the type information of the items because due to the const assertion, my array is not an array type anymore but is a constant tuple, so GetArrayElementType can't be applied on it.

Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • Is that a typo or why do you have `item1` twice? – Murat Karagöz May 13 '19 at 13:41
  • Possible duplicate of [TypeScript array to string literal type](https://stackoverflow.com/questions/44497388/typescript-array-to-string-literal-type) – Murat Karagöz May 13 '19 at 13:42
  • Does this answer your question? [Typescript derive union type from tuple/array values](https://stackoverflow.com/questions/45251664/typescript-derive-union-type-from-tuple-array-values) You even marked it yourself in the comment :D (https://stackoverflow.com/questions/45251664/typescript-derive-union-type-from-tuple-array-values/45257357#comment98860537_54399548) – Wilt Oct 22 '20 at 09:12

2 Answers2

24

If you want to use a conditional type you have to keep in mind that as const generates readonly arrays. So this should work as you expect it to:

export type GetArrayElementType<T extends readonly any[]> = T extends readonly (infer U)[] ? U : never;

export const MyConstArray = [
  'item1',
  'item2',
  'item3',
  'item4',
] as const;

export type MyConstArrayItem = GetArrayElementType<typeof MyConstArray>;

But the simpler solution is to not use a conditional type. Type index queries work better here:

export const MyConstArray = [
  'item1',
  'item2',
  'item3',
  'item4',
] as const;

export type MyConstArrayItem = typeof MyConstArray[number];
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
9

Can be done easily with:

type MyConstArrayItem = typeof MyConstArray[number]
Alexander Danilov
  • 3,038
  • 1
  • 30
  • 35