Typescript

Derive union type from tuplearray values

19 September 2026 · 12 min read

Derive union type from tuplearray values

TypeScript’s type system offers powerful features for creating robust and maintainable code. One such feature is the ability to derive a union type from tuple/array values. This technique allows you to define a type that encompasses all the possible values within a tuple or array, ensuring type safety and improving code clarity. By automatically generating union types based on your data structures, you can reduce redundancy and improve the overall flexibility of your TypeScript projects. This approach is particularly useful when dealing with predefined sets of values, such as configurations, enumerated values, or data schemas. Understanding how to leverage this capability can significantly enhance your TypeScript development workflow, leading to more reliable and efficient code. We’ll explore practical examples and use cases to illustrate the power and utility of this technique. This is especially important for developers looking to streamline their workflow and enhance type safety in their applications.

Understanding Union Types in TypeScript

A union type in TypeScript allows a variable to hold values of different types. It’s denoted by the pipe symbol (|). For example, string | number means a variable can be either a string or a number. Union types are crucial for representing values that can take on multiple forms. They enhance type safety by ensuring that only allowed types are assigned to a variable. This prevents unexpected runtime errors and makes your code more predictable and maintainable. Understanding union types is foundational for more advanced TypeScript concepts, like deriving union types from tuples or arrays.

Union types are particularly useful when dealing with functions that can accept different types of arguments or return different types of values based on input. For instance, a function that processes user input might accept either a string representing a username or a number representing a user ID. By defining the function’s argument type as a union (string | number), you can handle both scenarios in a type-safe manner. This reduces the need for runtime type checks and ensures that the function behaves predictably, regardless of the input type. As stated in the TypeScript documentation, “Union types are a powerful way to express that a value can be one of several types” [TypeScript Documentation].

Furthermore, union types enable better code completion and type checking within your IDE. When working with a variable of a union type, your IDE will suggest properties and methods that are common to all types in the union. This helps you write code more efficiently and reduces the likelihood of errors. For example, if you have a variable of type string | number, your IDE will only suggest methods that are available on both strings and numbers, such as toString(). This intelligent type checking makes your code more robust and easier to maintain over time.

Deriving Union Types from Tuples

Deriving a union type from a tuple involves extracting each element’s type and combining them into a single union type. TypeScript provides utility types like typeof and indexed access to accomplish this. The typeof operator obtains the type of a variable, and indexed access (e.g., Tuple[number]) allows you to access the type of elements within a tuple. Combining these techniques allows you to automatically generate a union type that accurately represents the possible values within the tuple. This approach enhances type safety and eliminates the need to manually define union types, reducing redundancy and potential errors.

Here’s an example of how to derive a union type from a tuple:

const myTuple = ['apple', 123, true] as const; type TupleUnion = typeof myTuple[number]; // "apple" | 123 | true 

In this example, myTuple is a tuple containing a string, a number, and a boolean. The as const assertion ensures that the tuple is treated as a read-only tuple literal. The TupleUnion type is then derived using typeof myTuple[number], which extracts the type of each element in the tuple and combines them into a union type: "apple" | 123 | true. This type accurately represents the possible values that can be assigned to a variable of type TupleUnion. The “as const” assertion is crucial for ensuring that the types are inferred as literal types, rather than just string, number, and boolean.

Using derived union types from tuples is incredibly beneficial for scenarios where you have predefined sets of values. Consider a configuration object where certain properties can only have specific values. By defining these values as a tuple and deriving a union type, you can ensure that only valid values are assigned to those properties. This approach improves code maintainability and reduces the risk of runtime errors caused by invalid configuration values.

Deriving Union Types from Arrays

Similar to tuples, you can also derive union types from arrays. However, because arrays are generally not treated as fixed-length structures like tuples, the approach is slightly different. TypeScript infers the type of an array’s elements as a single type, rather than individual types for each element. Therefore, to derive a union type from an array, you need to ensure that the array’s elements are treated as distinct literal types. This can be achieved using the as const assertion, which effectively transforms the array into a read-only tuple literal, allowing TypeScript to infer individual types for each element.

Here’s how you can derive a union type from an array:

const myArray = ['red', 'green', 'blue'] as const; type ArrayUnion = typeof myArray[number]; // "red" | "green" | "blue" 

In this example, myArray is an array of strings. The as const assertion ensures that the array is treated as a read-only tuple literal. The ArrayUnion type is then derived using typeof myArray[number], which extracts the type of each element in the array and combines them into a union type: "red" | "green" | "blue". This type accurately represents the possible values that can be assigned to a variable of type ArrayUnion.

Deriving union types from arrays is particularly useful when working with enumerated values or sets of predefined constants. For example, you might have an array of status codes, error messages, or UI themes. By deriving a union type from these arrays, you can ensure that only valid values are used throughout your application. This approach improves code clarity, reduces the risk of errors, and makes your code more maintainable.

Benefits of Using Derived Union Types

  • Type Safety: Ensures that only valid values are used, preventing runtime errors.
  • Code Clarity: Makes your code more readable and understandable by explicitly defining the possible values.
  • Maintainability: Reduces redundancy and potential errors by automatically generating union types.

Practical Examples and Use Cases

The ability to derive union type from tuple/array values has numerous practical applications in TypeScript development. Consider a scenario where you are building a UI component that accepts a limited set of color values. Instead of manually defining a union type for these colors, you can define them as an array and derive the union type automatically.

const colors = ['red', 'green', 'blue'] as const; type Color = typeof colors[number]; // "red" | "green" | "blue" function paintElement(element: HTMLElement, color: Color) { element.style.backgroundColor = color; } const myDiv = document.createElement('div'); paintElement(myDiv, 'red'); // Valid // paintElement(myDiv, 'purple'); // Error: Argument of type '"purple"' is not assignable to parameter of type '"red" | "green" | "blue"'. 

In this example, the Color type is derived from the colors array. The paintElement function then uses this type to ensure that only valid color values are passed as arguments. This approach provides strong type safety and prevents the function from being called with invalid color values. Another common use case is defining a set of allowed values for a configuration option. By deriving a union type from an array of allowed values, you can ensure that only valid configuration options are used throughout your application. This reduces the risk of errors and makes your code more maintainable.

Another powerful use case is in data validation. Imagine you’re receiving data from an API where a specific field can only have a few predefined values. You can create an array with those valid values and then derive a union type to validate the incoming data. This way, you ensure that your application only processes data that conforms to the expected schema, leading to more robust and reliable software. According to a study by Microsoft, using TypeScript can reduce bugs by up to 15% [Microsoft Research]. This reduction is largely due to the strong type checking capabilities of TypeScript, including the ability to derive union types from tuples and arrays.

Infographic here
Best Practices and Considerations ---------------------------------

When working with derived union types, it’s essential to follow best practices to ensure code clarity and maintainability. Always use the as const assertion when defining tuples or arrays from which you want to derive union types. This ensures that TypeScript infers the individual types of each element, rather than a broader type like string or number. Additionally, consider using descriptive names for your types to improve code readability. For example, instead of using a generic name like MyUnion, use a more specific name that reflects the purpose of the type, such as ColorType or StatusCode.

Here are some best practices for deriving union types:

  1. Use as const to ensure literal type inference.
  2. Use descriptive names for your types.
  3. Consider using type aliases to simplify complex union types.

Furthermore, be mindful of the size of your union types. While union types can be incredibly useful, excessively large union types can impact performance and make your code harder to understand. If you find yourself working with very large sets of values, consider alternative approaches, such as using enums or interfaces with discriminated unions. These approaches can provide better performance and maintainability for complex scenarios.

Finally, document your code thoroughly. Explain the purpose of your union types and how they are derived. This will help other developers (and your future self) understand your code more easily and make it easier to maintain over time. Clear and concise documentation is essential for any TypeScript project, especially when working with advanced type system features like derived union types. Remember, clear code is maintainable code, and using these techniques in conjunction with good documentation practices will make your codebase more robust and easier to work with.

Let’s emphasize this point as a featured snippet: Deriving union types from tuples or arrays in TypeScript enhances type safety by ensuring that only valid values are used, preventing runtime errors. It also makes your code more readable and understandable by explicitly defining the possible values. By automatically generating union types, you reduce redundancy and potential errors, improving maintainability.

FAQ

What is a union type in TypeScript?
A union type allows a variable to hold values of different types, denoted by the pipe symbol (`|`).
How do I derive a union type from a tuple?
Use `typeof tuple[number]`, ensuring the tuple is declared with `as const` for literal type inference.
Why should I use derived union types?
They improve type safety, code clarity, and maintainability by automatically generating types from your data structures.
If you've been wrestling with complex type definitions or seeking ways to streamline your TypeScript workflow, mastering the art of deriving union types from tuples and arrays can be a game-changer. It's a powerful technique that not only enhances type safety but also promotes code clarity and maintainability. Start experimenting with this approach in your projects, and you'll likely find it becoming an indispensable tool in your TypeScript arsenal. Ready to take your TypeScript skills to the next level? Explore our other articles on advanced TypeScript techniques and best practices. For further reading, check out the official TypeScript documentation [\[TypeScript Official Documentation\]](https://www.typescriptlang.org/docs/) and this article on advanced TypeScript patterns [\[Advanced TypeScript Patterns\]](https://www.patterns.dev/posts/typescript-pattern/). Feel free to also check our article on [TypeScript Generics](https://courthousezoological.com/n7sqp6kh?key=e6dd02bc5dbf461b97a9da08df84d31c). **Question & Answer :** Say I have an array:
const list = ['a', 'b', 'c'] 

Is it possible to derive from this value union type that is 'a' | 'b' | 'c'?

I want this because I want to define type which allows only values from static array, and also need to enumerate these values at runtime, so I use array.

Example how it can be implemented with an indexed object:

const indexed = {a: null, b: null, c: null} const list = Object.keys(index) type NeededUnionType = keyof typeof indexed 

Is it possible to do it without using an indexed map?

CURRENT ANSWER

In TypeScript 3.4 and above, you can use a const assertion to tell the compiler to retain the specific literal types of any literal values in an expression.

const list = ['a', 'b', 'c'] as const; // const assertion type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'; 

Playground link to code

UPDATE Feb 2019

In TypeScript 3.4, which should be released in March 2019 it will be possible to tell the compiler to infer the type of a tuple of literals as a tuple of literals, instead of as, say, string[], by using the as const syntax. This type of assertion causes the compiler to infer the narrowest type possible for a value, including making everything readonly. It should look like this:

const list = ['a', 'b', 'c'] as const; // TS3.4 syntax type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'; 

This will obviate the need for a helper function of any kind. Good luck again to all!


UPDATE July 2018

It looks like, starting with TypeScript 3.0, it will be possible for TypeScript to automatically infer tuple types. Once is released, the tuple() function you need can be succinctly written as:

export type Lit = string | number | boolean | undefined | null | void | {}; export const tuple = <T extends Lit[]>(...args: T) => args; 

And then you can use it like this:

const list = tuple('a','b','c'); // type is ['a','b','c'] type NeededUnionType = typeof list[number]; // 'a'|'b'|'c' 

Hope that works for people!


UPDATE December 2017

Since I posted this answer, I found a way to infer tuple types if you’re willing to add a function to your library. Check out the function tuple() in tuple.ts. Using it, you are able to write the following and not repeat yourself:

const list = tuple('a','b','c'); // type is ['a','b','c'] type NeededUnionType = typeof list[number]; // 'a'|'b'|'c' 

Good luck!


ORIGINAL July 2017

One problem is the literal ['a','b','c'] will be inferred as type string[], so the type system will forget about the specific values. You can force the type system to remember each value as a literal string:

const list = ['a' as 'a','b' as 'b','c' as 'c']; // infers as ('a'|'b'|'c')[] 

Or, maybe better, interpret the list as a tuple type:

const list: ['a','b','c'] = ['a','b','c']; // tuple 

This is annoying repetition, but at least it doesn’t introduce an extraneous object at runtime.

Now you can get your union like this:

type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'.