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:
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.
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:
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.
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:
- Transforming the properties of a type, for example, by creating a partial, readonly, or required version of a type.
- Creating utility types and functions that depend on type relationships, for example, by creating a function that filters out null values from an array.
- 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.