TYPESCRIPT / CHAPTER 12

Derive API types from one model

Advanced

Use mapped types to prevent duplicated contracts from drifting.

By the end of this chapter

  • Derive subsets and optional updates
  • Preserve field value types with indexed access
  • Recognize what type-level transformations do not execute

The idea

Several related APIs often use different views of one model: a full record, a public subset, and an update request. Deriving those views from the source type reduces duplicated field lists and inconsistent value types. Pick selects properties, Partial makes properties optional, and mapped types apply a transformation across a set of keys. These operations describe contracts; they do not copy or filter runtime objects.

Design the contract around the operation’s authority. An update type should expose only fields that callers may change, rather than blindly applying Partial to a record containing identity or audit fields. Optional updates also require a runtime merge policy for absent and explicitly provided values. Check what emitted code does separately from what the derived type permits at compile time.

TypeScript example
type Profile = {id: string; name: string; active: boolean};
type Edit = Partial<Pick<Profile, "name" | "active">>;
function apply(profile: Profile, edit: Edit): Profile {
  return {...profile, ...edit};
}
console.log(apply({id: "p1", name: "Ada", active: true}, {name: "Bo"}).name);
Result
Bo

The edit type excludes id and makes the allowed fields optional. The spread expression, not the type alias, performs the runtime merge.

Try it yourself

Derive a settings update type that permits only theme and pageSize, leaving accountId outside the update contract.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Which type permits optional changes to name but excludes id from the declared update fields?