In programming, particularly in languages that support union types, understanding how unions work with function parameters is crucial for writing flexible and type-safe code. Unions allow a variable to hold multiple types, which can be particularly useful when designing functions that need to handle different types of input. This concept is prevalent in languages like TypeScript, Rust, and others that support strong typing.
A union type is a type that can represent one of several different types. For example, in TypeScript, you can define a union type for a function parameter to accept either a string or a number. This flexibility can lead to more generic and reusable functions.
To define a union type in TypeScript, you use the pipe (`|`) operator. Here’s a simple example:
function printValue(value: string | number): void {
console.log(value);
}
In the example above, the `printValue` function can accept either a string or a number. This allows the function to be versatile while maintaining type safety.
Here’s how you can implement type narrowing in the `printValue` function:
function printValue(value: string | number): void {
if (typeof value === 'string') {
console.log(`String value: ${value}`);
} else {
console.log(`Number value: ${value}`);
}
}
In this example, the function checks the type of `value` before logging it, ensuring that the correct message format is used based on the type.
Consider the following function that does not use type guards:
function processValue(value: string | number): void {
// This will throw an error if value is a number
console.log(value.toUpperCase());
}
This function will fail at runtime if a number is passed in because `toUpperCase()` is a method that exists only on strings. Always ensure you handle each type appropriately.
In summary, unions are a powerful feature that can enhance the flexibility of function parameters. By following best practices and avoiding common pitfalls, developers can leverage union types to write more robust and maintainable code.