Skip to content

Improve propagation of modifiers in mapped types - #12826

Merged
Anders Hejlsberg (ahejlsberg) merged 4 commits into
masterfrom
mappedTypeModifiers2
Dec 10, 2016
Merged

Anders Hejlsberg (ahejlsberg) merged 4 commits into
masterfrom
mappedTypeModifiers2

Conversation

@ahejlsberg

@ahejlsberg Anders Hejlsberg (ahejlsberg) commented Dec 10, 2016 •

Copy link
Copy Markdown
Member

With this PR we more consistently propagate property modifiers in mapped types. For a given type parameter T, mapped types declared as { [P in keyof T]: X } or { [P in K]: X}, where K is a type parameter K extends keyof T, now propagate property modifiers from T. This in particular means that the predefined type Pick<T, K> now propagates property modifiers from T.

The intuitive way to think of this is that when a mapped type is known to operate on property names from a particular type (i.e. T in keyof T) or a subset of the property names of a particular type, then we propagate the property modifiers from that type.

interface Foo {
    a: string;
    b?: number;
}

function setState<T, K extends keyof T>(obj: T, props: Pick<T, K>) {
    for (let k in props) {
        obj[k] = props[k];
    }
}

let foo: Foo = { a: "hello", b: 42 };
setState(foo, { a: "test", b: 43 })
setState(foo, { a: "hi" });
setState(foo, { b: undefined });
setState(foo, { });
setState(foo, foo);
setState(foo, { a: undefined });  // Error
setState(foo, { c: true });  // Error

class C<T> {
    state: T;
    setState<K extends keyof T>(props: Pick<T, K>) {
        for (let k in props) {
            this.state[k] = props[k];
        }
    }
}

let c = new C<Foo>();
c.setState({ a: "test", b: 43 });
c.setState({ a: "hi" });
c.setState({ b: undefined });
c.setState({ });
c.setState(foo);
c.setState({ a: undefined });  // Error
c.setState({ c: true });  // Error

Note that because Pick<T, K> now propagates modifiers, it can no longer be used to "strip" modifiers.

Fixes #12793.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants