Skip to content

Distribute 'keyof' intersection types - #22300

Merged
Anders Hejlsberg (ahejlsberg) merged 4 commits into
masterfrom
distributeKeyofIntersection
Mar 3, 2018
Merged

Distribute 'keyof' intersection types#22300
Anders Hejlsberg (ahejlsberg) merged 4 commits into
masterfrom
distributeKeyofIntersection

Conversation

@ahejlsberg

@ahejlsberg Anders Hejlsberg (ahejlsberg) commented Mar 2, 2018

Copy link
Copy Markdown
Member

With this PR we transform keyof applied to an intersection type to a union of keyof applied to each intersection constituent. In other words, we rewrite types of the form keyof (A & B) to keyof A | keyof B.

Some examples:

type A = { a: string };
type B = { b: string };

type T1 = keyof (A & B);  // "a" | "b"
type T2<T> = keyof (T & B);  // keyof T | "b"
type T3<U> = keyof (A & U);  // "a" | keyof U
type T4<T, U> = keyof (T & U);  // keyof T | keyof U
type T5 = T2<A>;  // "a" | "b"
type T6 = T3<B>;  // "a" | "b"
type T7 = T4<A, B>;  // "a" | "b"

Fixes #22291.

@weswigham

Copy link
Copy Markdown
Member

keyof (string & {__brand: any}) and similar intersections needs tests documenting their behavior. (Other "empty" intersections like string & number, too)

@ahejlsberg
Anders Hejlsberg (ahejlsberg) deleted the distributeKeyofIntersection branch March 3, 2018 00:08
@Griffork

Griffork commented Mar 5, 2018

Copy link
Copy Markdown

From #22286
Just downloaded the nightly, this doesn't work:

type OptionalCommands<C extends string, T> = {[parameter in C]?: T};
type OptionalPropertyOrCommand<C extends string, T> = Partial<T> & OptionalCommands<C, T>;
class Thing<T> {
    thing: OptionalPropertyOrCommand<"this" | "that", T>;
    myfoo<V extends keyof T>(property: V, newvalue: T[V]) {
        this.thing[property] = newvalue;
    }
    myfoo2(newthing: T) {
        this.thing["that"] = newthing;
    }
}

EDIT: Was fixed, apparently nightlys aren't nightly.

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

Labels

None yet

4 participants