In TypeScript, type aliases create type definitions that can be reused throughout the code. This is unlike type unions and intersections, where the explicit type information is used repetitively.
1. Syntax
Type aliases require the type keyword and a name. They can be created in two ways.
They can be set as an object that describes the members and their respective types.
Define types based on conditions within the type definition itself
Useful for creating types that vary depending on properties or values.
type myType = {
memberOne: string;
memberTwo?: number;
}
let favoriteNum: myType = {"my favorite number is ", 42}
They can also refer to other known types, like a union type.
type myType = string | number;
let favoriteNum: myType = '42';
Later on, whenever the name is used, TypeScript will assume this refers to the aliased value. Type aliases are similar to interfaces in terms of syntax and behavior. However, a key difference is that an interface can have members added later on whereas type aliases can’t be changed after being defined.
2. Type Guards and Type Assertions
In this example, the StringsIsh type alias can be used in place of the type union with several members. When applied to the logAllStrings() function:
type StringsIsh = string | string[] | null | undefined;
function logAllStrings(values: StringsIsh) {
if (values === null || typeof values === 'undefined') return;
if (typeof values === 'string') {
console.log(values);
} else {
values.forEach(logAllStrings);
}
}
logAllStrings('hello'); // Ok
logAllStrings(['hello', 'world']); // Also Ok
function isString(value: string | number): value is string {
return typeof value === "string";
}
let userInput: string | number = prompt("Enter your name");
if (isString(userInput)) {
console.log(`Hello, ${userInput}!`); // Now we know userInput is a string
}
Typescript
The first type guard checks to see if values matches either null or undefined in the StringIsh type alias. Next, the if/else-statement checks for a base case of values being of type string. Otherwise, it recursively invokes logAllStrings again.
3. Type Aliases as Generics
Type aliases may be generic and may contain any type description, including:
Primitives
Literals
Object types
The following Result type may contain a value, T, or an object containing the value, { value: T }:
type Result<T> = T | { value: T };
let value: Result<string> = 'hello'; // Ok
let other: Result<string> = { value: 'world' }; // Also Ok
Utility Types
Predefined types that provide common operations on other types.
Examples include Partial, Pick, Record, and more.
type Todo = {
title: string;
completed: boolean;
};
type PartialTodo = Partial<Todo>; // All properties optional
let partialTodo: PartialTodo = { title: "Finish this task" };
5. Key Points:
Type aliases don't create new types; they just provide alternative names.
Use aliases strategically for frequently used complex types.
Aliases can't be used for primitive types like number or string when type inference is already clear.
Beyond the Basics:
You can create nested type aliases for even more complex scenarios.
Aliases can be used with generics to create reusable components that work with various data types.