Create a Union type from an Array or Object in TypeScript

avatar

Borislav Hadzhiev

3 min

banner

Photo from Unsplash

Table of Contents #

  1. Create a Union type from an Array in TypeScript
  2. Create a Union type from an Object's Values or Keys in TS

Create a Union type from an Array in TypeScript #

To create a union type from an array:

  1. Use as const to convert the array to a readonly tuple.
  2. Use typeof arr[number] to get a type containing all of the array's elements.
  3. The resulting type will be a union of all of the elements in the array.
index.ts
// ๐Ÿ‘‡๏ธ const sizes: readonly ["small", "medium", "large"] const sizes = ['small', 'medium', 'large'] as const; // ๐Ÿ‘‡๏ธ type SizesUnion = "small" | "medium" | "large" type SizesUnion = typeof sizes[number];

We used as const to set the properties of the array to readonly and indicate to the language that the type of the expression will not be widened, e.g. from ['small', 'medium'] to string[].

The as const syntax is called a const assertion in TypeScript.

The array in the example becomes a readonly tuple, so its contents cannot be changed.

index.ts
// ๐Ÿ‘‡๏ธ const sizes: readonly ["small", "medium", "large"] const sizes = ['small', 'medium', 'large'] as const; // โ›”๏ธ Error: Property 'push' does not exist // on type 'readonly ["small", "medium", "large"]' sizes.push('test');

If you try to change the contents of the array, you would get an error.

This way TypeScript can infer the type of the array as ['small', 'medium', 'large'] and not string[].

The typeof operator allows us to get the type of a variable.

index.ts
// ๐Ÿ‘‡๏ธ const sizes: readonly ["small", "medium", "large"] const sizes = ['small', 'medium', 'large'] as const; // ๐Ÿ‘‡๏ธ type SizesUnion = "small" | "medium" | "large" type SizesUnion = typeof sizes[number]; // ๐Ÿ‘‡๏ธ type T = readonly ["small", "medium", "large"] type T = typeof sizes;

Arrays have a numeric index signature.

index.ts
// ๐Ÿ‘‡๏ธ const sizes: readonly ["small", "medium", "large"] const sizes = ['small', 'medium', 'large'] as const; // ๐Ÿ‘‡๏ธ ['0', '1', '2'] console.log(Object.keys(sizes));

This is why we used the [number] syntax to get a union containing all of the values in the array.

We are basically getting all of the values in the array that can be indexed with a number key.

Create a Union type from an Object's Values or Keys in TS #

To create a union type from an object's values or keys:

  1. Use as const to set the properties of the object to readonly.
  2. Use keyof typeof to get a type of the keys in the object.
  3. Use the keys to get a union of the values.
index.ts
// ๐Ÿ‘‡๏ธ const obj: {readonly name: "Bobby Hadz"; readonly country: "Chile";} const obj = { name: 'Bobby Hadz', country: 'Chile', } as const; // ๐Ÿ‘‡๏ธ type UValues = "Bobby Hadz" | "Chile" type UValues = (typeof obj)[keyof typeof obj]; // ๐Ÿ‘‡๏ธ type UKeys = "name" | "country" type UKeys = keyof typeof obj;

We used as const to set the properties of the object to readonly and indicate to the language that the type of the expression will not be widened, e.g. from {name: "Bobby Hadz"} to {name: string}.

The as const syntax is called a const assertion in TypeScript.

The object in the example contains readonly properties, so their values cannot be changed.

index.ts
// ๐Ÿ‘‡๏ธ const obj: {readonly name: "Bobby Hadz"; readonly country: "Chile";} const obj = { name: 'Bobby Hadz', country: 'Chile', } as const; // โ›”๏ธ Error: Cannot assign to 'name' because it is a // read-only property. obj.name = 'James';

If you try to change the value of a property, you would get an error.

This way TypeScript can infer the type of the object as {name: 'Bobby hadz'; country: 'Chile'} instead of {name: string; country: string;}.

We used keyof typeof to create a union of the object's keys.

index.ts
// ๐Ÿ‘‡๏ธ const obj: {readonly name: "Bobby Hadz"; readonly country: "Chile";} const obj = { name: 'Bobby Hadz', country: 'Chile', } as const; // ๐Ÿ‘‡๏ธ type UKeys = "name" | "country" type UKeys = keyof typeof obj;

We can use the same approach to get a union of the object's values.

index.ts
// ๐Ÿ‘‡๏ธ const obj: {readonly name: "Bobby Hadz"; readonly country: "Chile";} const obj = { name: 'Bobby Hadz', country: 'Chile', } as const; // ๐Ÿ‘‡๏ธ type UValues = "Bobby Hadz" | "Chile" type UValues = typeof obj[keyof typeof obj]; // ๐Ÿ‘‡๏ธ type UKeys = "name" | "country" type UKeys = keyof typeof obj;

We used the typeof operator to get the type of the object and then indexed the type with all of the keys to get a union containing the object's values.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2023 Borislav Hadzhiev