diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 10247343525..80f3d8a3eb7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7642,11 +7642,9 @@ namespace ts { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } - left = filterType(left, t => !(t.flags & TypeFlags.Nullable)); if (left.flags & TypeFlags.Never) { return right; } - right = filterType(right, t => !(t.flags & TypeFlags.Nullable)); if (right.flags & TypeFlags.Never) { return left; } diff --git a/tests/baselines/reference/spreadUnion.symbols b/tests/baselines/reference/spreadUnion.symbols index 40a63d56d49..bef8f5522d7 100644 --- a/tests/baselines/reference/spreadUnion.symbols +++ b/tests/baselines/reference/spreadUnion.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion.ts === +=== tests/cases/conformance/types/spread/spreadUnion.ts === var union: { a: number } | { b: string }; >union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) >a : Symbol(a, Decl(spreadUnion.ts, 0, 12)) diff --git a/tests/baselines/reference/spreadUnion.types b/tests/baselines/reference/spreadUnion.types index 9e5ac1cffd5..fb1ef5f2018 100644 --- a/tests/baselines/reference/spreadUnion.types +++ b/tests/baselines/reference/spreadUnion.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion.ts === +=== tests/cases/conformance/types/spread/spreadUnion.ts === var union: { a: number } | { b: string }; >union : { a: number; } | { b: string; } >a : number diff --git a/tests/baselines/reference/spreadUnion2.js b/tests/baselines/reference/spreadUnion2.js index b98046463c3..6e49770617a 100644 --- a/tests/baselines/reference/spreadUnion2.js +++ b/tests/baselines/reference/spreadUnion2.js @@ -3,25 +3,25 @@ declare const undefinedUnion: { a: number } | undefined; declare const nullUnion: { b: number } | null; declare const nullAndUndefinedUnion: null | undefined; -var o1: { a: number }; +var o1: {} | { a: number }; var o1 = { ...undefinedUnion }; -var o2: { b: number }; +var o2: {} | { b: number }; var o2 = { ...nullUnion }; -var o3: { a: number, b: number }; +var o3: {} | { b: number } | { a: number } | { a: number, b: number }; var o3 = { ...undefinedUnion, ...nullUnion }; var o3 = { ...nullUnion, ...undefinedUnion }; -var o4: { a: number }; +var o4: {} | { a: number }; var o4 = { ...undefinedUnion, ...undefinedUnion }; -var o5: { b: number }; +var o5: {} | { b: number }; var o5 = { ...nullUnion, ...nullUnion }; -var o6: { }; var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; -var o6 = { ...nullAndUndefinedUnion }; +var o7 = { ...nullAndUndefinedUnion }; + //// [spreadUnion2.js] var __assign = (this && this.__assign) || Object.assign || function(t) { @@ -43,6 +43,5 @@ var o4; var o4 = __assign({}, undefinedUnion, undefinedUnion); var o5; var o5 = __assign({}, nullUnion, nullUnion); -var o6; var o6 = __assign({}, nullAndUndefinedUnion, nullAndUndefinedUnion); -var o6 = __assign({}, nullAndUndefinedUnion); +var o7 = __assign({}, nullAndUndefinedUnion); diff --git a/tests/baselines/reference/spreadUnion2.symbols b/tests/baselines/reference/spreadUnion2.symbols index 05703fc32bd..c4d1f19b6d9 100644 --- a/tests/baselines/reference/spreadUnion2.symbols +++ b/tests/baselines/reference/spreadUnion2.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion2.ts === +=== tests/cases/conformance/types/spread/spreadUnion2.ts === declare const undefinedUnion: { a: number } | undefined; >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) >a : Symbol(a, Decl(spreadUnion2.ts, 0, 31)) @@ -10,26 +10,28 @@ declare const nullUnion: { b: number } | null; declare const nullAndUndefinedUnion: null | undefined; >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) -var o1: { a: number }; +var o1: {} | { a: number }; >o1 : Symbol(o1, Decl(spreadUnion2.ts, 4, 3), Decl(spreadUnion2.ts, 5, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 4, 9)) +>a : Symbol(a, Decl(spreadUnion2.ts, 4, 14)) var o1 = { ...undefinedUnion }; >o1 : Symbol(o1, Decl(spreadUnion2.ts, 4, 3), Decl(spreadUnion2.ts, 5, 3)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) -var o2: { b: number }; +var o2: {} | { b: number }; >o2 : Symbol(o2, Decl(spreadUnion2.ts, 7, 3), Decl(spreadUnion2.ts, 8, 3)) ->b : Symbol(b, Decl(spreadUnion2.ts, 7, 9)) +>b : Symbol(b, Decl(spreadUnion2.ts, 7, 14)) var o2 = { ...nullUnion }; >o2 : Symbol(o2, Decl(spreadUnion2.ts, 7, 3), Decl(spreadUnion2.ts, 8, 3)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) -var o3: { a: number, b: number }; +var o3: {} | { b: number } | { a: number } | { a: number, b: number }; >o3 : Symbol(o3, Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 10, 9)) ->b : Symbol(b, Decl(spreadUnion2.ts, 10, 20)) +>b : Symbol(b, Decl(spreadUnion2.ts, 10, 14)) +>a : Symbol(a, Decl(spreadUnion2.ts, 10, 30)) +>a : Symbol(a, Decl(spreadUnion2.ts, 10, 46)) +>b : Symbol(b, Decl(spreadUnion2.ts, 10, 57)) var o3 = { ...undefinedUnion, ...nullUnion }; >o3 : Symbol(o3, Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3)) @@ -41,33 +43,30 @@ var o3 = { ...nullUnion, ...undefinedUnion }; >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) -var o4: { a: number }; +var o4: {} | { a: number }; >o4 : Symbol(o4, Decl(spreadUnion2.ts, 14, 3), Decl(spreadUnion2.ts, 15, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 14, 9)) +>a : Symbol(a, Decl(spreadUnion2.ts, 14, 14)) var o4 = { ...undefinedUnion, ...undefinedUnion }; >o4 : Symbol(o4, Decl(spreadUnion2.ts, 14, 3), Decl(spreadUnion2.ts, 15, 3)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) -var o5: { b: number }; +var o5: {} | { b: number }; >o5 : Symbol(o5, Decl(spreadUnion2.ts, 17, 3), Decl(spreadUnion2.ts, 18, 3)) ->b : Symbol(b, Decl(spreadUnion2.ts, 17, 9)) +>b : Symbol(b, Decl(spreadUnion2.ts, 17, 14)) var o5 = { ...nullUnion, ...nullUnion }; >o5 : Symbol(o5, Decl(spreadUnion2.ts, 17, 3), Decl(spreadUnion2.ts, 18, 3)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) -var o6: { }; ->o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3), Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3)) - var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; ->o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3), Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3)) +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3)) >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) -var o6 = { ...nullAndUndefinedUnion }; ->o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3), Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3)) +var o7 = { ...nullAndUndefinedUnion }; +>o7 : Symbol(o7, Decl(spreadUnion2.ts, 21, 3)) >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) diff --git a/tests/baselines/reference/spreadUnion2.types b/tests/baselines/reference/spreadUnion2.types index 97fbb9838c7..ea3364f296b 100644 --- a/tests/baselines/reference/spreadUnion2.types +++ b/tests/baselines/reference/spreadUnion2.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion2.ts === +=== tests/cases/conformance/types/spread/spreadUnion2.ts === declare const undefinedUnion: { a: number } | undefined; >undefinedUnion : { a: number; } | undefined >a : number @@ -12,72 +12,71 @@ declare const nullAndUndefinedUnion: null | undefined; >nullAndUndefinedUnion : null | undefined >null : null -var o1: { a: number }; ->o1 : { a: number; } +var o1: {} | { a: number }; +>o1 : {} | { a: number; } >a : number var o1 = { ...undefinedUnion }; ->o1 : { a: number; } ->{ ...undefinedUnion } : { a: number; } +>o1 : {} | { a: number; } +>{ ...undefinedUnion } : {} | { a: number; } >undefinedUnion : { a: number; } | undefined -var o2: { b: number }; ->o2 : { b: number; } +var o2: {} | { b: number }; +>o2 : {} | { b: number; } >b : number var o2 = { ...nullUnion }; ->o2 : { b: number; } ->{ ...nullUnion } : { b: number; } +>o2 : {} | { b: number; } +>{ ...nullUnion } : {} | { b: number; } >nullUnion : { b: number; } | null -var o3: { a: number, b: number }; ->o3 : { a: number; b: number; } +var o3: {} | { b: number } | { a: number } | { a: number, b: number }; +>o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>b : number +>a : number >a : number >b : number var o3 = { ...undefinedUnion, ...nullUnion }; ->o3 : { a: number; b: number; } ->{ ...undefinedUnion, ...nullUnion } : { b: number; a: number; } +>o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>{ ...undefinedUnion, ...nullUnion } : {} | { b: number; } | { a: number; } | { b: number; a: number; } >undefinedUnion : { a: number; } | undefined >nullUnion : { b: number; } | null var o3 = { ...nullUnion, ...undefinedUnion }; ->o3 : { a: number; b: number; } ->{ ...nullUnion, ...undefinedUnion } : { a: number; b: number; } +>o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>{ ...nullUnion, ...undefinedUnion } : {} | { a: number; } | { b: number; } | { a: number; b: number; } >nullUnion : { b: number; } | null >undefinedUnion : { a: number; } | undefined -var o4: { a: number }; ->o4 : { a: number; } +var o4: {} | { a: number }; +>o4 : {} | { a: number; } >a : number var o4 = { ...undefinedUnion, ...undefinedUnion }; ->o4 : { a: number; } ->{ ...undefinedUnion, ...undefinedUnion } : { a: number; } +>o4 : {} | { a: number; } +>{ ...undefinedUnion, ...undefinedUnion } : {} | { a: number; } | { a: number; } | { a: number; } >undefinedUnion : { a: number; } | undefined >undefinedUnion : { a: number; } | undefined -var o5: { b: number }; ->o5 : { b: number; } +var o5: {} | { b: number }; +>o5 : {} | { b: number; } >b : number var o5 = { ...nullUnion, ...nullUnion }; ->o5 : { b: number; } ->{ ...nullUnion, ...nullUnion } : { b: number; } +>o5 : {} | { b: number; } +>{ ...nullUnion, ...nullUnion } : {} | { b: number; } | { b: number; } | { b: number; } >nullUnion : { b: number; } | null >nullUnion : { b: number; } | null -var o6: { }; ->o6 : {} - var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; ->o6 : {} ->{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {} +>o6 : {} | {} | {} | {} +>{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {} | {} | {} | {} >nullAndUndefinedUnion : null | undefined >nullAndUndefinedUnion : null | undefined -var o6 = { ...nullAndUndefinedUnion }; ->o6 : {} ->{ ...nullAndUndefinedUnion } : {} +var o7 = { ...nullAndUndefinedUnion }; +>o7 : {} | {} +>{ ...nullAndUndefinedUnion } : {} | {} >nullAndUndefinedUnion : null | undefined diff --git a/tests/baselines/reference/spreadUnion3.errors.txt b/tests/baselines/reference/spreadUnion3.errors.txt new file mode 100644 index 00000000000..5f5b620685c --- /dev/null +++ b/tests/baselines/reference/spreadUnion3.errors.txt @@ -0,0 +1,31 @@ +tests/cases/conformance/types/spread/spreadUnion3.ts(2,5): error TS2322: Type '{ y: number; } | { y: string; }' is not assignable to type '{ y: string; }'. + Type '{ y: number; }' is not assignable to type '{ y: string; }'. + Types of property 'y' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: Property 'a' does not exist on type '{} | {} | { a: number; }'. + Property 'a' does not exist on type '{}'. + + +==== tests/cases/conformance/types/spread/spreadUnion3.ts (2 errors) ==== + function f(x: { y: string } | undefined): { y: string } { + return { y: 123, ...x } // y: string | number + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ y: number; } | { y: string; }' is not assignable to type '{ y: string; }'. +!!! error TS2322: Type '{ y: number; }' is not assignable to type '{ y: string; }'. +!!! error TS2322: Types of property 'y' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + } + f(undefined) + + + function g(t?: { a: number } | null): void { + let b = { ...t }; + let c: number = b.a; // might not have 'a' + ~ +!!! error TS2339: Property 'a' does not exist on type '{} | {} | { a: number; }'. +!!! error TS2339: Property 'a' does not exist on type '{}'. + } + g() + g(undefined) + g(null) + \ No newline at end of file diff --git a/tests/baselines/reference/spreadUnion3.js b/tests/baselines/reference/spreadUnion3.js new file mode 100644 index 00000000000..2aaf9efeb78 --- /dev/null +++ b/tests/baselines/reference/spreadUnion3.js @@ -0,0 +1,36 @@ +//// [spreadUnion3.ts] +function f(x: { y: string } | undefined): { y: string } { + return { y: 123, ...x } // y: string | number +} +f(undefined) + + +function g(t?: { a: number } | null): void { + let b = { ...t }; + let c: number = b.a; // might not have 'a' +} +g() +g(undefined) +g(null) + + +//// [spreadUnion3.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +function f(x) { + return __assign({ y: 123 }, x); // y: string | number +} +f(undefined); +function g(t) { + var b = __assign({}, t); + var c = b.a; // might not have 'a' +} +g(); +g(undefined); +g(null); diff --git a/tests/cases/compiler/spreadUnion.ts b/tests/cases/conformance/types/spread/spreadUnion.ts similarity index 100% rename from tests/cases/compiler/spreadUnion.ts rename to tests/cases/conformance/types/spread/spreadUnion.ts diff --git a/tests/cases/compiler/spreadUnion2.ts b/tests/cases/conformance/types/spread/spreadUnion2.ts similarity index 67% rename from tests/cases/compiler/spreadUnion2.ts rename to tests/cases/conformance/types/spread/spreadUnion2.ts index 25dba81c0df..e2f72879915 100644 --- a/tests/cases/compiler/spreadUnion2.ts +++ b/tests/cases/conformance/types/spread/spreadUnion2.ts @@ -4,22 +4,21 @@ declare const undefinedUnion: { a: number } | undefined; declare const nullUnion: { b: number } | null; declare const nullAndUndefinedUnion: null | undefined; -var o1: { a: number }; +var o1: {} | { a: number }; var o1 = { ...undefinedUnion }; -var o2: { b: number }; +var o2: {} | { b: number }; var o2 = { ...nullUnion }; -var o3: { a: number, b: number }; +var o3: {} | { b: number } | { a: number } | { a: number, b: number }; var o3 = { ...undefinedUnion, ...nullUnion }; var o3 = { ...nullUnion, ...undefinedUnion }; -var o4: { a: number }; +var o4: {} | { a: number }; var o4 = { ...undefinedUnion, ...undefinedUnion }; -var o5: { b: number }; +var o5: {} | { b: number }; var o5 = { ...nullUnion, ...nullUnion }; -var o6: { }; var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; -var o6 = { ...nullAndUndefinedUnion }; \ No newline at end of file +var o7 = { ...nullAndUndefinedUnion }; diff --git a/tests/cases/conformance/types/spread/spreadUnion3.ts b/tests/cases/conformance/types/spread/spreadUnion3.ts new file mode 100644 index 00000000000..c16acbdf7d3 --- /dev/null +++ b/tests/cases/conformance/types/spread/spreadUnion3.ts @@ -0,0 +1,14 @@ +// @strictNullChecks: true +function f(x: { y: string } | undefined): { y: string } { + return { y: 123, ...x } // y: string | number +} +f(undefined) + + +function g(t?: { a: number } | null): void { + let b = { ...t }; + let c: number = b.a; // might not have 'a' +} +g() +g(undefined) +g(null)