Skip to content

Commit

Permalink
Maintain modifiers on Omit (#31205)
Browse files Browse the repository at this point in the history
Maintain modifiers on `Omit`
  • Loading branch information
DanielRosenwasser committed May 10, 2019
2 parents 0c9db71 + d7434a0 commit 39e9a2b
Show file tree
Hide file tree
Showing 16 changed files with 273 additions and 51 deletions.
4 changes: 1 addition & 3 deletions src/lib/es5.d.ts
Expand Up @@ -1446,9 +1446,7 @@ type Extract<T, U> = T extends U ? T : never;
/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = {
[P in Exclude<keyof T, K>]: T[P]
};
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

/**
* Exclude null and undefined from T
Expand Down
12 changes: 6 additions & 6 deletions tests/baselines/reference/genericIsNeverEmptyObject.types
Expand Up @@ -2,18 +2,18 @@
// Repro from #29067

function test<T extends { a: string }>(obj: T) {
>test : <T extends { a: string; }>(obj: T) => Omit<T, "a"> & { b: string; }
>test : <T extends { a: string; }>(obj: T) => Pick<T, Exclude<keyof T, "a">> & { b: string; }
>a : string
>obj : T

let { a, ...rest } = obj;
>a : string
>rest : Omit<T, "a">
>rest : Pick<T, Exclude<keyof T, "a">>
>obj : T

return { ...rest, b: a };
>{ ...rest, b: a } : Omit<T, "a"> & { b: string; }
>rest : Omit<T, "a">
>{ ...rest, b: a } : Pick<T, Exclude<keyof T, "a">> & { b: string; }
>rest : Pick<T, Exclude<keyof T, "a">>
>b : string
>a : string
}
Expand All @@ -30,7 +30,7 @@ let o2: { b: string, x: number } = test(o1);
>o2 : { b: string; x: number; }
>b : string
>x : number
>test(o1) : Omit<{ a: string; x: number; }, "a"> & { b: string; }
>test : <T extends { a: string; }>(obj: T) => Omit<T, "a"> & { b: string; }
>test(o1) : Pick<{ a: string; x: number; }, "x"> & { b: string; }
>test : <T extends { a: string; }>(obj: T) => Pick<T, Exclude<keyof T, "a">> & { b: string; }
>o1 : { a: string; x: number; }

16 changes: 8 additions & 8 deletions tests/baselines/reference/genericObjectRest.types
Expand Up @@ -16,32 +16,32 @@ function f1<T extends { a: string, b: number }>(obj: T) {
let { a: a1, ...r1 } = obj;
>a : any
>a1 : string
>r1 : Omit<T, "a">
>r1 : Pick<T, Exclude<keyof T, "a">>
>obj : T

let { a: a2, b: b2, ...r2 } = obj;
>a : any
>a2 : string
>b : any
>b2 : number
>r2 : Omit<T, "a" | "b">
>r2 : Pick<T, Exclude<keyof T, "a" | "b">>
>obj : T

let { 'a': a3, ...r3 } = obj;
>a3 : string
>r3 : Omit<T, "a">
>r3 : Pick<T, Exclude<keyof T, "a">>
>obj : T

let { ['a']: a4, ...r4 } = obj;
>'a' : "a"
>a4 : string
>r4 : Omit<T, "a">
>r4 : Pick<T, Exclude<keyof T, "a">>
>obj : T

let { [a]: a5, ...r5 } = obj;
>a : "a"
>a5 : string
>r5 : Omit<T, "a">
>r5 : Pick<T, Exclude<keyof T, "a">>
>obj : T
}

Expand All @@ -68,7 +68,7 @@ function f2<T extends { [sa]: string, [sb]: number }>(obj: T) {
>a1 : string
>sb : unique symbol
>b1 : number
>r1 : Omit<T, unique symbol | unique symbol>
>r1 : Pick<T, Exclude<keyof T, unique symbol | unique symbol>>
>obj : T
}

Expand All @@ -83,7 +83,7 @@ function f3<T, K1 extends keyof T, K2 extends keyof T>(obj: T, k1: K1, k2: K2) {
>a1 : T[K1]
>k2 : K2
>a2 : T[K2]
>r1 : Omit<T, K1 | K2>
>r1 : Pick<T, Exclude<keyof T, K1 | K2>>
>obj : T
}

Expand All @@ -104,7 +104,7 @@ function f4<K1 extends keyof Item, K2 extends keyof Item>(obj: Item, k1: K1, k2:
>a1 : Item[K1]
>k2 : K2
>a2 : Item[K2]
>r1 : Omit<Item, K1 | K2>
>r1 : Pick<Item, Exclude<"a", K1 | K2> | Exclude<"b", K1 | K2> | Exclude<"c", K1 | K2>>
>obj : Item
}

6 changes: 3 additions & 3 deletions tests/baselines/reference/literalTypeWidening.types
Expand Up @@ -443,14 +443,14 @@ function test<T extends { a: string, b: string }>(obj: T): T {

let { a, ...rest } = obj;
>a : string
>rest : Omit<T, "a">
>rest : Pick<T, Exclude<keyof T, "a">>
>obj : T

return { a: 'hello', ...rest } as T;
>{ a: 'hello', ...rest } as T : T
>{ a: 'hello', ...rest } : { a: string; } & Omit<T, "a">
>{ a: 'hello', ...rest } : { a: string; } & Pick<T, Exclude<keyof T, "a">>
>a : string
>'hello' : "hello"
>rest : Omit<T, "a">
>rest : Pick<T, Exclude<keyof T, "a">>
}

4 changes: 2 additions & 2 deletions tests/baselines/reference/mappedTypeConstraints.symbols
Expand Up @@ -132,9 +132,9 @@ const modifier = <T extends TargetProps>(targetProps: T) => {
>targetProps : Symbol(targetProps, Decl(mappedTypeConstraints.ts, 30, 41))

rest.foo;
>rest.foo : Symbol(foo)
>rest.foo : Symbol(foo, Decl(mappedTypeConstraints.ts, 25, 20))
>rest : Symbol(rest, Decl(mappedTypeConstraints.ts, 31, 13))
>foo : Symbol(foo)
>foo : Symbol(foo, Decl(mappedTypeConstraints.ts, 25, 20))

};

4 changes: 2 additions & 2 deletions tests/baselines/reference/mappedTypeConstraints.types
Expand Up @@ -98,12 +98,12 @@ const modifier = <T extends TargetProps>(targetProps: T) => {

let {bar, ...rest} = targetProps;
>bar : string
>rest : Omit<T, "bar">
>rest : Pick<T, Exclude<keyof T, "bar">>
>targetProps : T

rest.foo;
>rest.foo : T["foo"]
>rest : Omit<T, "bar">
>rest : Pick<T, Exclude<keyof T, "bar">>
>foo : T["foo"]

};
Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/objectRestNegative.types
Expand Up @@ -36,18 +36,18 @@ function stillMustBeLast({ ...mustBeLast, a }: { a: number, b: string }): void {
>b : string
}
function generic<T extends { x, y }>(t: T) {
>generic : <T extends { x: any; y: any; }>(t: T) => Omit<T, "x">
>generic : <T extends { x: any; y: any; }>(t: T) => Pick<T, Exclude<keyof T, "x">>
>x : any
>y : any
>t : T

let { x, ...rest } = t;
>x : any
>rest : Omit<T, "x">
>rest : Pick<T, Exclude<keyof T, "x">>
>t : T

return rest;
>rest : Omit<T, "x">
>rest : Pick<T, Exclude<keyof T, "x">>
}

let rest: { b: string }
Expand Down
27 changes: 27 additions & 0 deletions tests/baselines/reference/omitTypeHelperModifiers01.errors.txt
@@ -0,0 +1,27 @@
tests/cases/compiler/omitTypeHelperModifiers01.ts(16,7): error TS2540: Cannot assign to 'c' because it is a read-only property.


==== tests/cases/compiler/omitTypeHelperModifiers01.ts (1 errors) ====
type A = {
a: number;
b?: string;
readonly c: boolean;
d: unknown;
};

type B = Omit<A, 'a'>;

function f(x: B) {
const b = x.b;
x.b = "hello";
x.b = undefined;

const c = x.c;
x.c = true;
~
!!! error TS2540: Cannot assign to 'c' because it is a read-only property.

const d = x.d;
x.d = d;
}

34 changes: 34 additions & 0 deletions tests/baselines/reference/omitTypeHelperModifiers01.js
@@ -0,0 +1,34 @@
//// [omitTypeHelperModifiers01.ts]
type A = {
a: number;
b?: string;
readonly c: boolean;
d: unknown;
};

type B = Omit<A, 'a'>;

function f(x: B) {
const b = x.b;
x.b = "hello";
x.b = undefined;

const c = x.c;
x.c = true;

const d = x.d;
x.d = d;
}


//// [omitTypeHelperModifiers01.js]
"use strict";
function f(x) {
var b = x.b;
x.b = "hello";
x.b = undefined;
var c = x.c;
x.c = true;
var d = x.d;
x.d = d;
}
69 changes: 69 additions & 0 deletions tests/baselines/reference/omitTypeHelperModifiers01.symbols
@@ -0,0 +1,69 @@
=== tests/cases/compiler/omitTypeHelperModifiers01.ts ===
type A = {
>A : Symbol(A, Decl(omitTypeHelperModifiers01.ts, 0, 0))

a: number;
>a : Symbol(a, Decl(omitTypeHelperModifiers01.ts, 0, 10))

b?: string;
>b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 1, 14))

readonly c: boolean;
>c : Symbol(c, Decl(omitTypeHelperModifiers01.ts, 2, 15))

d: unknown;
>d : Symbol(d, Decl(omitTypeHelperModifiers01.ts, 3, 24))

};

type B = Omit<A, 'a'>;
>B : Symbol(B, Decl(omitTypeHelperModifiers01.ts, 5, 2))
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
>A : Symbol(A, Decl(omitTypeHelperModifiers01.ts, 0, 0))

function f(x: B) {
>f : Symbol(f, Decl(omitTypeHelperModifiers01.ts, 7, 22))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>B : Symbol(B, Decl(omitTypeHelperModifiers01.ts, 5, 2))

const b = x.b;
>b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 10, 9))
>x.b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 1, 14))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 1, 14))

x.b = "hello";
>x.b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 1, 14))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 1, 14))

x.b = undefined;
>x.b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 1, 14))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>b : Symbol(b, Decl(omitTypeHelperModifiers01.ts, 1, 14))
>undefined : Symbol(undefined)

const c = x.c;
>c : Symbol(c, Decl(omitTypeHelperModifiers01.ts, 14, 9))
>x.c : Symbol(c, Decl(omitTypeHelperModifiers01.ts, 2, 15))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>c : Symbol(c, Decl(omitTypeHelperModifiers01.ts, 2, 15))

x.c = true;
>x.c : Symbol(c, Decl(omitTypeHelperModifiers01.ts, 2, 15))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>c : Symbol(c, Decl(omitTypeHelperModifiers01.ts, 2, 15))

const d = x.d;
>d : Symbol(d, Decl(omitTypeHelperModifiers01.ts, 17, 9))
>x.d : Symbol(d, Decl(omitTypeHelperModifiers01.ts, 3, 24))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>d : Symbol(d, Decl(omitTypeHelperModifiers01.ts, 3, 24))

x.d = d;
>x.d : Symbol(d, Decl(omitTypeHelperModifiers01.ts, 3, 24))
>x : Symbol(x, Decl(omitTypeHelperModifiers01.ts, 9, 11))
>d : Symbol(d, Decl(omitTypeHelperModifiers01.ts, 3, 24))
>d : Symbol(d, Decl(omitTypeHelperModifiers01.ts, 17, 9))
}

72 changes: 72 additions & 0 deletions tests/baselines/reference/omitTypeHelperModifiers01.types
@@ -0,0 +1,72 @@
=== tests/cases/compiler/omitTypeHelperModifiers01.ts ===
type A = {
>A : A

a: number;
>a : number

b?: string;
>b : string | undefined

readonly c: boolean;
>c : boolean

d: unknown;
>d : unknown

};

type B = Omit<A, 'a'>;
>B : Pick<A, "b" | "c" | "d">

function f(x: B) {
>f : (x: Pick<A, "b" | "c" | "d">) => void
>x : Pick<A, "b" | "c" | "d">

const b = x.b;
>b : string | undefined
>x.b : string | undefined
>x : Pick<A, "b" | "c" | "d">
>b : string | undefined

x.b = "hello";
>x.b = "hello" : "hello"
>x.b : string | undefined
>x : Pick<A, "b" | "c" | "d">
>b : string | undefined
>"hello" : "hello"

x.b = undefined;
>x.b = undefined : undefined
>x.b : string | undefined
>x : Pick<A, "b" | "c" | "d">
>b : string | undefined
>undefined : undefined

const c = x.c;
>c : boolean
>x.c : boolean
>x : Pick<A, "b" | "c" | "d">
>c : boolean

x.c = true;
>x.c = true : true
>x.c : any
>x : Pick<A, "b" | "c" | "d">
>c : any
>true : true

const d = x.d;
>d : unknown
>x.d : unknown
>x : Pick<A, "b" | "c" | "d">
>d : unknown

x.d = d;
>x.d = d : unknown
>x.d : unknown
>x : Pick<A, "b" | "c" | "d">
>d : unknown
>d : unknown
}

0 comments on commit 39e9a2b

Please sign in to comment.