Skip to content
tezvyn:
Menu

TypeScript: Modify Properties with Mapped Type Modifiers

Source: typescriptlang.orgMediumHow cards are made

Mapped type modifiers let you add or remove readonly and ? from a type's properties. Use them to create a fully required type from an optional one, or a mutable version of a readonly object. The footgun: remember the - prefix to *remove* modifiers.

Why it exists

To avoid manually creating slight variations of a type. If you have a User type and need a PartialUser for a form or a ReadonlyUser for configuration, you don't want to copy-paste the entire type definition. Mapped types let you derive new types programmatically, keeping your code DRY (Don't Repeat Yourself).

The mental model

Think of mapped type modifiers as a factory for type shapes. You provide an input type and an instruction—like "make everything mutable" or "make everything required"—and it outputs a new type with those changes applied to every property, without you having to touch each one individually.

How it works

A mapped type iterates over the keys of a source type. Modifiers use + and - prefixes to add or remove readonly and optional (?) markers. A + or no prefix adds the modifier, while a - prefix removes it. The syntax is +/-readonly [Property in keyof Type] for mutability and [Property in keyof Type]+/-?: for optionality. For example, -readonly makes a property mutable, and -? makes a property required.

When to use it

Use modifiers to create common variations of a base type. Three key scenarios are: first, creating a mutable version of a readonly type (e.g., {-readonly [P in keyof T]: T[P]}); second, making all properties of an optional type required (e.g., {[P in keyof T]-?: T[P]}); third, making all properties optional, which is what the built-in Partial<T> utility type does.

When not to use it

Don't use mapped type modifiers if you only need to change one or two properties; using Pick or Omit with a type intersection (&) is often simpler. Also, if you need to rename the keys themselves, you'd use the as keyword for key remapping, which is a different feature of mapped types.

One canonical example

Let's make a type with optional properties fully required. Given a type MaybeUser = { id: string; name?: string; age?: number; }, we can create a Concrete utility type: type Concrete<T> = { [P in keyof T]-?: T[P] };. Applying this as type User = Concrete<MaybeUser>; results in a new User type where id, name, and age are all required, non-optional properties.

Interview question

Which mapped type modifier syntax makes all properties of a type required?

  • a.[P in keyof T]+?: T[P]
  • b.[P in keyof T]-?: T[P]Correct
  • c.[P in keyof T]?: T[P]
  • d.[P in keyof T]!: T[P]
Why?

The `-?` syntax explicitly removes the optional modifier from a property, making it required. Option A, `+?`, would add or retain optionality, which is the opposite of making properties required.

Just read this? Test yourself on what you have been reading.

Read the original → typescriptlang.org

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on typescript — each one lists the topics its interview covers.

See open roles