Improved control over mapped type modifiers

Mapped types support adding a readonly or ? modifier to a mapped property, but they did not provide support the ability to remove modifiers.This matters in homomorphic mapped types which by default preserve the modifiers of the underlying type.

TypeScript 2.8 adds the ability for a mapped type to either add or remove a particular modifier.Specifically, a readonly or ? property modifier in a mapped type can now be prefixed with either + or - to indicate that the modifier should be added or removed.

Example

  1. type MutableRequired<T> = { -readonly [P in keyof T]-?: T[P] }; // Remove readonly and ?
  2. type ReadonlyPartial<T> = { +readonly [P in keyof T]+?: T[P] }; // Add readonly and ?

A modifier with no + or - prefix is the same as a modifier with a + prefix. So, the ReadonlyPartial<T> type above corresponds to

  1. type ReadonlyPartial<T> = { readonly [P in keyof T]?: T[P] }; // Add readonly and ?

Using this ability, lib.d.ts now has a new Required<T> type.This type strips ? modifiers from all properties of T, thus making all properties required.

Example

  1. type Required<T> = { [P in keyof T]-?: T[P] };

Note that in —strictNullChecks mode, when a homomorphic mapped type removes a ? modifier from a property in the underlying type it also removes undefined from the type of that property:

Example

  1. type Foo = { a?: string }; // Same as { a?: string | undefined }
  2. type Bar = Required<Foo>; // Same as { a: string }