Skip to main content

Mapped & Conditional Types in TypeScript (Live Playground)

In this tutorial, we will explore mapped and conditional types in TypeScript. Understanding how to use mapped and conditional types will help you write more flexible and type-safe code.

Mapped Types

Mapped types allow you to create a new type by transforming the properties of an existing type. They can be used to create readonly, partial, or required versions of a type, among other things:

TypeScript
interface Person {
name: string;
age: number;
}

type ReadonlyPerson = Readonly<Person>;

const person: ReadonlyPerson = { name: 'John Doe', age: 30 };
person.age = 31; // Error: Cannot assign to 'age' because it is a read-only property

In this example, we create an interface Person and a mapped type ReadonlyPerson that makes all properties of Person readonly. We then create a person object of type ReadonlyPerson and demonstrate that its properties cannot be modified.

Live Playground, Try it Yourself

Conditional Types

Conditional types allow you to create a type that depends on a condition (a type relationship test). They can be used to create more flexible and type-safe utility types and functions:

TypeScript
type NonNullable<T> = T extends null | undefined ? never : T;

function filterNull<T>(array: T[]): NonNullable<T>[] {
return array.filter((item): item is NonNullable<T> => item !== null && item !== undefined);
}

const arrayWithNulls: Array<string | null> = ['a', null, 'b', null, 'c'];
const filteredArray: Array<string> = filterNull(arrayWithNulls);

console.log(filteredArray); // Output: [ 'a', 'b', 'c' ]

In this example, we create a conditional type NonNullable that removes null and undefined from a type. We then create a filterNull function that filters out null and undefined values from an array and returns an array of non-nullable items.

Live Playground, Try it Yourself

Using Mapped and Conditional Types

Mapped and conditional types can be used in a variety of scenarios to create more flexible and type-safe code:

  1. Transforming the properties of a type, for example, by creating a partial, readonly, or required version of a type.
  2. Creating utility types and functions that depend on type relationships, for example, by creating a function that filters out null values from an array.
  3. Writing more expressive and type-safe code in scenarios where types depend on other types, for example, by creating a function that maps over an array and returns an array of the same type.

Conclusion

In this tutorial, we have explored mapped and conditional types in TypeScript. Understanding how to use mapped and conditional types effectively will enable you to create more flexible and type-safe code.