TypeScript - Union Types: A Friendly Introduction for Beginners

Hello there, future coding superstar! ? Are you ready to dive into the wonderful world of TypeScript and learn about one of its most powerful features? Today, we're going to explore Union Types, a concept that might sound intimidating at first, but I promise you'll find it super useful and even fun by the end of this tutorial!

TypeScript - Union

As your friendly neighborhood computer teacher, I've seen countless students light up when they grasp this concept. So, let's embark on this journey together, shall we?

What Are Union Types?

Before we jump into the nitty-gritty, let's start with a simple analogy. Imagine you have a magic box that can hold either a toy car or a stuffed animal, but not both at the same time. That's kind of what a Union Type is in TypeScript – it's a way to tell our code that a variable can be one of several types.

Now, let's get our hands dirty with some code!

Syntax: Union Literal

The basic syntax for a Union Type uses the pipe symbol (|) to separate the different types. It's like telling TypeScript, "Hey, this can be this OR that!"

let myFavorite: string | number;

myFavorite = "TypeScript"; // This is valid
console.log(myFavorite); // Output: TypeScript

myFavorite = 42; // This is also valid
console.log(myFavorite); // Output: 42

// myFavorite = true; // This would cause an error

In this example, myFavorite can be either a string or a number. It's like our magic box that can hold either a word or a number, but not anything else. If we tried to put a boolean (like true) in there, TypeScript would wave its magic wand and show us an error.

Union Type Variable

Let's expand on our previous example and see how Union Types can make our code more flexible:

type Pet = "cat" | "dog" | "fish";
let myPet: Pet;

myPet = "cat"; // This is valid
console.log(`I have a ${myPet}`); // Output: I have a cat

myPet = "dog"; // This is also valid
console.log(`I have a ${myPet}`); // Output: I have a dog

// myPet = "elephant"; // This would cause an error

Here, we've created a custom type called Pet that can only be one of three specific strings. It's like having a pet store that only sells cats, dogs, and fish. If you try to buy an elephant, sorry, no can do!

Union Type and Function Parameter

Union Types really shine when we use them with functions. They allow our functions to be more versatile without losing type safety. Let's look at an example:

function printId(id: number | string) {
    console.log(`Your ID is: ${id}`);
}

printId(101); // Output: Your ID is: 101
printId("202"); // Output: Your ID is: 202

// printId(true); // This would cause an error

In this function, printId can accept either a number or a string as an argument. It's like a universal ID card reader that can process both numeric and text-based IDs. But try to swipe your boolean ID card, and it'll politely refuse!

Union Type and Arrays

Now, let's level up and see how Union Types work with arrays. Brace yourself for some array magic!

let mixedArray: (number | string)[] = [1, "two", 3, "four", 5];

console.log(mixedArray); // Output: [1, "two", 3, "four", 5]

mixedArray.push(6); // This is valid
mixedArray.push("seven"); // This is also valid

// mixedArray.push(true); // This would cause an error

console.log(mixedArray); // Output: [1, "two", 3, "four", 5, 6, "seven"]

Here, we've created an array that can contain both numbers and strings. It's like a playlist that can include both track numbers and song titles. But try to sneak a boolean in there, and TypeScript will catch you red-handed!

Practical Use Cases

Now that we've covered the basics, let's look at some real-world scenarios where Union Types can save the day:

  1. API Responses: When working with APIs, sometimes the data you receive can be of different types. Union Types help you handle these variations gracefully.
type ApiResponse = {
    status: "success" | "error";
    data: string | number | null;
};

function handleResponse(response: ApiResponse) {
    if (response.status === "success") {
        console.log(`Success! Data: ${response.data}`);
    } else {
        console.log("An error occurred");
    }
}

handleResponse({ status: "success", data: "User profile loaded" });
handleResponse({ status: "error", data: null });
  1. Configuration Options: When creating configurable functions, Union Types allow you to provide a set of valid options.
type Color = "red" | "green" | "blue";
type Size = "small" | "medium" | "large";

function createButton(color: Color, size: Size) {
    console.log(`Creating a ${color} button of size ${size}`);
}

createButton("red", "medium"); // Valid
// createButton("yellow", "extra-large"); // This would cause an error

Common Union Type Methods

Here's a table of some common methods you can use with Union Types:

Method Description Example
typeof Checks the type of a value typeof x === "string"
instanceof Checks if an object is an instance of a specific class x instanceof Date
in Checks if a property exists in an object "name" in x
Array.isArray() Checks if a value is an array Array.isArray(x)

Conclusion

Phew! We've covered a lot of ground today, haven't we? Union Types might seem a bit tricky at first, but they're incredibly powerful tools in your TypeScript toolkit. They allow you to write more flexible and robust code, catching potential errors before they even happen.

Remember, coding is like learning a new language – it takes practice and patience. Don't be discouraged if you don't get it right away. Keep experimenting, keep coding, and before you know it, you'll be using Union Types like a pro!

As we wrap up, I'm reminded of a student who once told me, "Union Types are like a Swiss Army knife for my code!" And you know what? They were absolutely right. So go forth, young coder, and may your Union Types be ever in your favor! ??

Credits: Image by storyset