Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve propagation of modifiers in mapped types #12826

Merged
merged 4 commits into from
Dec 10, 2016

Conversation

ahejlsberg
Copy link
Member

@ahejlsberg ahejlsberg commented Dec 10, 2016

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