JavaScript > TypeScript > TypeScript Basics > Type aliases

Defining and Using Type Aliases in TypeScript

This snippet demonstrates how to define and use type aliases in TypeScript to create more readable and maintainable code. Type aliases allow you to give a new name to an existing type, which can be especially useful for complex types or unions.

Basic Type Alias Definition

This code defines a type alias called StringOrNumber. It represents a union type that can be either a string or a number. The variable value is then declared to be of type StringOrNumber, allowing it to hold either a string or a number. Trying to assign a boolean to value will cause a TypeScript error.

type StringOrNumber = string | number;

let value: StringOrNumber;

value = "Hello"; // Valid
value = 123;     // Valid
//value = true;  // Invalid - Type 'boolean' is not assignable to type 'StringOrNumber'.

console.log(value);

Type Alias with Object Types

Here, the type alias Point is defined as an object type with properties x and y, both of which are numbers. This allows us to easily reuse this type definition whenever we need to represent a point in 2D space.

type Point = {
  x: number;
  y: number;
};

const myPoint: Point = {
  x: 10,
  y: 20,
};

console.log(myPoint.x, myPoint.y);

Type Alias with Tuple Types

This example demonstrates defining a type alias Color for a tuple type representing RGB color values (red, green, blue), where each value is a number. Tuple types maintain order and the number of elements.

type Color = [number, number, number]; // RGB

const red: Color = [255, 0, 0];
const green: Color = [0, 255, 0];
const blue: Color = [0, 0, 255];

console.log(red, green, blue);

Type Alias with Function Types

In this code, MathOperation is a type alias for a function that takes two numbers as arguments and returns a number. This is then used to define the types for add and subtract functions.

type MathOperation = (x: number, y: number) => number;

const add: MathOperation = (x, y) => x + y;
const subtract: MathOperation = (x, y) => x - y;

console.log(add(5, 3));      // Output: 8
console.log(subtract(5, 3)); // Output: 2

Real-Life Use Case

Type aliases are incredibly useful when working with complex data structures from APIs. For example, if an API returns user data with many nested properties, a type alias can make the code more readable and manageable. Imagine dealing with JSON data describing a product with properties like name, price, description, variants (an array of objects), and so on. Defining a Product type alias allows you to easily type-check and auto-complete properties across your application.

Best Practices

Use descriptive names for your type aliases to improve code readability. Avoid creating type aliases for simple primitive types (like just renaming string to MyString). Type aliases shine when dealing with complex types like unions, intersections, tuples, or object shapes. Consider using interfaces instead of type aliases if you need to use inheritance.

When to use them

Use type aliases when you want to give a descriptive name to a complex type, improving code readability and maintainability. This is especially helpful when working with union types, tuple types, or object types. They are also useful when you want to define function types for callbacks or event handlers.

Interview Tip

Be prepared to explain the difference between type aliases and interfaces. While both can be used to define object shapes, interfaces can be extended and implemented by classes, while type aliases cannot. Type aliases can, however, define union types and tuples, which interfaces cannot. A common interview question involves choosing the correct tool for a given scenario.

Alternatives

Interfaces are the primary alternative to type aliases for defining object shapes. Consider interfaces when you need to support inheritance (extends) or implement an object type within a class (implements). Enums are another alternative for representing a set of named constants, though they serve a different purpose than type aliases.

Pros

  • Readability: Improve code readability by giving meaningful names to complex types.
  • Maintainability: Make it easier to update and maintain code by centralizing type definitions.
  • Code Reuse: Reuse type definitions across multiple parts of the application.

Cons

  • No Inheritance: Type aliases do not support inheritance like interfaces do.
  • Debugging: Debugging can sometimes be more challenging if types are heavily aliased, as the original type might be obscured. However, using good naming conventions can mitigate this.

FAQ

  • What is the difference between a type alias and an interface?

    Both type aliases and interfaces are used to define the shape of an object. However, interfaces can be extended and implemented by classes, while type aliases cannot. Type aliases can also define union types and tuples, which interfaces cannot. Choose the right tool based on your specific needs. If you need inheritance, use an interface; otherwise, a type alias might be more suitable, especially for unions or tuples.
  • Can I use type aliases with generic types?

    Yes, you can use type aliases with generic types. This allows you to create reusable type definitions that can work with different types. For example: type Response = { data: T; status: number; };. This creates a generic Response type that can hold any type of data.