Increasing Type Safety with Union Types in TypeScript
Stephen Burke
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.