Mapped type modifier inference by ahejlsberg · Pull Request #12589 · microsoft/TypeScript

This PR improves our handling of readonly and optional modifiers in mapped type inference. When inferring to a homomorphic (structure preserving) mapped type { readonly [P in keyof T]: X }, no readonly modifiers will be present in the type inferred for T (because it is known that the mapping will add it). Likewise, when inferring to a mapped type { [P in keyof T]?: X }, no ? modifers will be present in the type inferred for T. In effect, readonly and optional modifiers in the target are used to indicate that those modifiers should be stripped in the inferred type.

declare function validate<T>(obj: { [P in keyof T]?: T[P] }): T;
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
declare function validateAndClone<T>(obj: { readonly [P in keyof T]?: T[P] }): T;

type Foo = {
    a?: number;
    readonly b: string;
}

function test(foo: Foo) {
    let x = validate(foo);  // { a: number, readonly b: string }
    let y = clone(foo);  // { a?: number, b: string }
    let z = validateAndClone(foo);  // { a: number, b: string }
}