TypeScript Mapped Types (original) (raw)
Last Updated : 24 Jan, 2025
Mapped types in TypeScript allow you to create new types by transforming the properties of existing types.
- They enable modifications like making properties optional, read-only, or altering their types.
- Mapped types help reduce code duplication and enhance type safety by automating type transformations.
- They are particularly useful for creating variations of types without manually redefining each property. JavaScript `
type User = { id: number; name: string; email: string; };
type PartialUser = { [P in keyof User]?: User[P]; };
`
- PartialUser is a new type where each property of User is made optional.
- The keyof operator retrieves all keys from User, and the mapped type iterates over each key, marking them as optional with ?.
**Output:
**const user1: PartialUser = { id: 1 }; const user2: PartialUser = {}; const user3: PartialUser = { id: 2, name: "Alice" };
**More Example of TypeScript Mapped Types
**Creating Readonly Properties
JavaScript `
type User = { id: number; name: string; email: string; };
type ReadonlyUser = { readonly [P in keyof User]: User[P]; };
const user: ReadonlyUser = { id: 1, name: "Alice", email: "alice@example.com" }; user.id = 2;
`
- ReadonlyUser is a new type where all properties of User are marked as readonly.
- Attempting to modify any property of user will result in a compile-time error.
**Output:
Error: Cannot assign to 'id' because it is a read-only property.
**Creating Nullable Properties
JavaScript `
type Product = { name: string; price: number; inStock: boolean; };
type NullableProduct = { [P in keyof Product]: Product[P] | null; };
const product: NullableProduct = { name: "Laptop", price: null, inStock: true };
`
- NullableProduct is a new type where each property of Product can be its original type or null.
- This allows properties to explicitly have a null value, indicating the absence of a value.
**Output:
{ name: "Laptop", price: null, inStock: true }
Renaming Properties with Template Literals
JavaScript ``
type Person = { firstName: string; lastName: string; };
type PrefixedPerson = {
[P in keyof Person as person${Capitalize<P>}
]: Person[P];
};
const person: PrefixedPerson = { personFirstName: "John", personLastName: "Doe" };
``
- PrefixedPerson creates a new type by prefixing each property of Person with 'person' and capitalizing the original property name.
- This demonstrates how to transform property names using template literal types and the Capitalize utility type.
**Output:
{ personFirstName: "John", personLastName: "Doe" }
Best Practices for Using TypeScript Mapped Types
- **Keep Transformations Simple: Avoid overly complex nested transformations to maintain readability and ease of maintenance.
- **Ensure Type Safety: Leverage mapped types to enforce consistent property transformations, enhancing type safety across your codebase.
- **Combine with Utility Types: Utilize built-in utility types like Partial, Readonly, Pick, and Omit to simplify common transformations.