Increasing Type Safety with Union Types in TypeScript

TypeScript's union-types provide a powerful mechanism for increasing type safety and ensuring that variables only hold specific, predefined values. By leveraging union types, developers can create more robust and predictable code that minimizes runtime errors and enhances the overall quality of their applications.

Many programming languages, including TypeScript, provide a feature known as "union types." This powerful mechanism allows developers to define a variable or parameter that can hold values of multiple types. By leveraging union types, developers can significantly increase the type safety of their code and ensure that variables only hold specific, predefined values.

In this article, we'll explore the concept of union types in TypeScript and demonstrate how they can be used to create more robust and predictable code. We'll also discuss common use cases for union types and provide examples to illustrate their practical applications.

Understanding Union Types

In TypeScript, a union type is a type formed by combining two or more other types. This allows a variable to hold values of different types at different points in time. Union types are defined using the | symbol, which acts as a logical "or" operator between the constituent types.

Consider the following example:

let result: string | number;

In this example, the variable result is declared with a union type that can hold either string values or number values. This means that result can be assigned a value of type string, a value of type number, or even a value that is compatible with both types.

Practical Use Cases for Union Types

Let's explore a common pattern in a React application with useState and see how we can improve the type safety.

import { useState } from 'react';

const statusOptions = ['pending', 'approved', 'rejected'];

const SomeComponent = () => {
  const [status, setStatus] = useState('pending');
  // TypeScript infers the type of `status` as `string`
  // ...
};

In this example, the status state variable is initialized with the value 'pending'. However, TypeScript does not automatically infer the type of the status variable based on the initial value. As a result, the status variable is implicitly typed as string, which means it can hold any string value, not just the specific values 'pending', 'approved', or 'rejected'.

To increase the type safety of the status variable, we can use a union type to explicitly define the set of allowed values:

import { useState } from 'react';

const statusOptions = ['pending', 'approved', 'rejected'] as const;
const Status = typeof statusOptions[number];

const SomeComponent = () => {
  const [status, setStatus] = useState<Status>('pending');
  // Now inferred as `'pending' | 'approved' | 'rejected'`
  // TypeScript now enforces that `status` can only hold specific values
  // defined in the `statusOptions` array as a union type.
  // ...
};

By using a union type, we explicitly specify that the status variable can only hold the values 'pending', 'approved', or 'rejected. This ensures that the status variable is more type-safe and that TypeScript will enforce the correct usage of these values throughout the application.


Thank you for reading! If you enjoyed this post, feel free to share it with your friends and colleagues. For more insights on web development, technology trends, and digital innovation, stay tuned to this blog.

Prev:

Eliminating Header Flicker in React: Using the IntersectionObserver API link
Next:

Launching a Personal Websites with Astro.js link