diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 47ea4442e9e..8177939fe61 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3055,7 +3055,10 @@ namespace ts { function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type { if (source.flags & TypeFlags.Union) { - return getUnionType(map((source).types, t => getRestType(t, properties, symbol))); + const types = filter((source).types, t => !(t.flags & TypeFlags.Nullable)); + if (types.length) { + return getUnionType(map(types, t => getRestType(t, properties, symbol))); + } } const members = createMap(); @@ -6111,11 +6114,29 @@ namespace ts { } if (left.flags & TypeFlags.Union) { - return getUnionType(map((left).types, t => getSpreadType(t, right, isFromObjectLiteral))); + const types = filter((left).types, t => !(t.flags & TypeFlags.Nullable)); + if (types.length) { + return getUnionType(map(types, t => getSpreadType(t, right, isFromObjectLiteral))); + } + else { + left = emptyObjectType + } + } + else if (left.flags & TypeFlags.Nullable) { + left = emptyObjectType; } if (right.flags & TypeFlags.Union) { - return getUnionType(map((right).types, t => getSpreadType(left, t, isFromObjectLiteral))); + const types = filter((right).types, t => !(t.flags & TypeFlags.Nullable)); + if (types.length) { + return getUnionType(map(types, t => getSpreadType(left, t, isFromObjectLiteral))); + } + else { + right = emptyObjectType + } + } + else if (right.flags & TypeFlags.Nullable) { + right = emptyObjectType; } const members = createMap(); @@ -11528,7 +11549,7 @@ namespace ts { } function isValidSpreadType(type: Type): boolean { - if (type.flags & TypeFlags.Any) { + if (type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined)) { return true; } if (type.flags & TypeFlags.Object) { @@ -11540,6 +11561,7 @@ namespace ts { return false; } } + return true; } return false; } diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index dc6a356708f..e92b685b910 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -7,8 +7,6 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,1): error TS2322 Property 's' is missing in type '{ b: boolean; }'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,36): error TS2300: Duplicate identifier 'b'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,53): error TS2300: Duplicate identifier 'b'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(32,20): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(33,24): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/spread/objectSpreadNegative.ts(34,19): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/spread/objectSpreadNegative.ts(35,19): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,20): error TS2698: Spread types may only be created from object types. @@ -20,7 +18,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(58,14): error TS269 tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (17 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (15 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -68,11 +66,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS269 // null, undefined and primitives are not allowed let spreadNull = { ...null }; - ~~~~~~~ -!!! error TS2698: Spread types may only be created from object types. let spreadUndefind = { ...undefined }; - ~~~~~~~~~~~~ -!!! error TS2698: Spread types may only be created from object types. let spreadNum = { ...12 }; ~~~~~ !!! error TS2698: Spread types may only be created from object types. diff --git a/tests/baselines/reference/restInvalidArgumentType.errors.txt b/tests/baselines/reference/restInvalidArgumentType.errors.txt index e7cf1ba6f9f..fff2c7b3563 100644 --- a/tests/baselines/reference/restInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/restInvalidArgumentType.errors.txt @@ -9,14 +9,12 @@ tests/cases/compiler/restInvalidArgumentType.ts(44,13): error TS2700: Rest types tests/cases/compiler/restInvalidArgumentType.ts(45,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(47,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(48,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(50,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(51,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(55,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(56,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types may only be created from object types. -==== tests/cases/compiler/restInvalidArgumentType.ts (16 errors) ==== +==== tests/cases/compiler/restInvalidArgumentType.ts (14 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -88,12 +86,8 @@ tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types ~~~ !!! error TS2700: Rest types may only be created from object types. - var {...r14} = u; // Error - ~~~ -!!! error TS2700: Rest types may only be created from object types. - var {...r15} = n; // Error - ~~~ -!!! error TS2700: Rest types may only be created from object types. + var {...r14} = u; // OK + var {...r15} = n; // OK var {...r16} = a; // OK diff --git a/tests/baselines/reference/restInvalidArgumentType.js b/tests/baselines/reference/restInvalidArgumentType.js index 23b46a2f775..22a547880eb 100644 --- a/tests/baselines/reference/restInvalidArgumentType.js +++ b/tests/baselines/reference/restInvalidArgumentType.js @@ -48,8 +48,8 @@ function f(p1: T, p2: T[]) { var {...r12} = num; // Error var {...r13} = str; // Error - var {...r14} = u; // Error - var {...r15} = n; // Error + var {...r14} = u; // OK + var {...r15} = n; // OK var {...r16} = a; // OK @@ -106,8 +106,8 @@ function f(p1, p2) { var r11 = __rest(intersection_premitive, []); // Error, intersection with generic type parameter var r12 = __rest(num, []); // Error var r13 = __rest(str, []); // Error - var r14 = __rest(u, []); // Error - var r15 = __rest(n, []); // Error + var r14 = __rest(u, []); // OK + var r15 = __rest(n, []); // OK var r16 = __rest(a, []); // OK var r17 = __rest(literal_string, []); // Error var r18 = __rest(literal_number, []); // Error diff --git a/tests/baselines/reference/restUnion.js b/tests/baselines/reference/restUnion.js new file mode 100644 index 00000000000..beaf514808b --- /dev/null +++ b/tests/baselines/reference/restUnion.js @@ -0,0 +1,36 @@ +//// [restUnion.ts] +var union: { a: number, c: boolean } | { a: string, b: string }; + +var rest1: { c: boolean } | { b: string }; +var {a, ...rest1 } = union; + + +var undefinedUnion: { n: number } | undefined; +var rest2: {}; +var {n, ...rest2 } = undefinedUnion; + + +var nullUnion: { n: number } | null; +var rest3: {}; +var {n, ...rest3 } = nullUnion; + + +//// [restUnion.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var union; +var rest1; +var a = union.a, rest1 = __rest(union, ["a"]); +var undefinedUnion; +var rest2; +var n = undefinedUnion.n, rest2 = __rest(undefinedUnion, ["n"]); +var nullUnion; +var rest3; +var n = nullUnion.n, rest3 = __rest(nullUnion, ["n"]); diff --git a/tests/baselines/reference/restUnion.symbols b/tests/baselines/reference/restUnion.symbols new file mode 100644 index 00000000000..660c85badb4 --- /dev/null +++ b/tests/baselines/reference/restUnion.symbols @@ -0,0 +1,44 @@ +=== tests/cases/compiler/restUnion.ts === +var union: { a: number, c: boolean } | { a: string, b: string }; +>union : Symbol(union, Decl(restUnion.ts, 0, 3)) +>a : Symbol(a, Decl(restUnion.ts, 0, 12)) +>c : Symbol(c, Decl(restUnion.ts, 0, 23)) +>a : Symbol(a, Decl(restUnion.ts, 0, 40)) +>b : Symbol(b, Decl(restUnion.ts, 0, 51)) + +var rest1: { c: boolean } | { b: string }; +>rest1 : Symbol(rest1, Decl(restUnion.ts, 2, 3), Decl(restUnion.ts, 3, 7)) +>c : Symbol(c, Decl(restUnion.ts, 2, 12)) +>b : Symbol(b, Decl(restUnion.ts, 2, 29)) + +var {a, ...rest1 } = union; +>a : Symbol(a, Decl(restUnion.ts, 3, 5)) +>rest1 : Symbol(rest1, Decl(restUnion.ts, 2, 3), Decl(restUnion.ts, 3, 7)) +>union : Symbol(union, Decl(restUnion.ts, 0, 3)) + + +var undefinedUnion: { n: number } | undefined; +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion.ts, 6, 3)) +>n : Symbol(n, Decl(restUnion.ts, 6, 21)) + +var rest2: {}; +>rest2 : Symbol(rest2, Decl(restUnion.ts, 7, 3), Decl(restUnion.ts, 8, 7)) + +var {n, ...rest2 } = undefinedUnion; +>n : Symbol(n, Decl(restUnion.ts, 8, 5), Decl(restUnion.ts, 13, 5)) +>rest2 : Symbol(rest2, Decl(restUnion.ts, 7, 3), Decl(restUnion.ts, 8, 7)) +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion.ts, 6, 3)) + + +var nullUnion: { n: number } | null; +>nullUnion : Symbol(nullUnion, Decl(restUnion.ts, 11, 3)) +>n : Symbol(n, Decl(restUnion.ts, 11, 16)) + +var rest3: {}; +>rest3 : Symbol(rest3, Decl(restUnion.ts, 12, 3), Decl(restUnion.ts, 13, 7)) + +var {n, ...rest3 } = nullUnion; +>n : Symbol(n, Decl(restUnion.ts, 8, 5), Decl(restUnion.ts, 13, 5)) +>rest3 : Symbol(rest3, Decl(restUnion.ts, 12, 3), Decl(restUnion.ts, 13, 7)) +>nullUnion : Symbol(nullUnion, Decl(restUnion.ts, 11, 3)) + diff --git a/tests/baselines/reference/restUnion.types b/tests/baselines/reference/restUnion.types new file mode 100644 index 00000000000..9837466684b --- /dev/null +++ b/tests/baselines/reference/restUnion.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/restUnion.ts === +var union: { a: number, c: boolean } | { a: string, b: string }; +>union : { a: number; c: boolean; } | { a: string; b: string; } +>a : number +>c : boolean +>a : string +>b : string + +var rest1: { c: boolean } | { b: string }; +>rest1 : { c: boolean; } | { b: string; } +>c : boolean +>b : string + +var {a, ...rest1 } = union; +>a : string | number +>rest1 : { c: boolean; } | { b: string; } +>union : { a: number; c: boolean; } | { a: string; b: string; } + + +var undefinedUnion: { n: number } | undefined; +>undefinedUnion : { n: number; } +>n : number + +var rest2: {}; +>rest2 : {} + +var {n, ...rest2 } = undefinedUnion; +>n : number +>rest2 : {} +>undefinedUnion : { n: number; } + + +var nullUnion: { n: number } | null; +>nullUnion : { n: number; } +>n : number +>null : null + +var rest3: {}; +>rest3 : {} + +var {n, ...rest3 } = nullUnion; +>n : number +>rest3 : {} +>nullUnion : { n: number; } + diff --git a/tests/baselines/reference/restUnion2.js b/tests/baselines/reference/restUnion2.js new file mode 100644 index 00000000000..d7466981645 --- /dev/null +++ b/tests/baselines/reference/restUnion2.js @@ -0,0 +1,38 @@ +//// [restUnion2.ts] + +declare const undefinedUnion: { n: number } | undefined; +var rest2: { n: number }; +var {...rest2 } = undefinedUnion; + + +declare const nullUnion: { n: number } | null; +var rest3: { n: number }; +var {...rest3 } = nullUnion; + + +declare const nullAndUndefinedUnion: null | undefined; +var rest4: { }; +var {...rest4 } = nullAndUndefinedUnion; + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +var rest5: { n: number, s: string }; +var {...rest5 } = unionWithIntersection; + +//// [restUnion2.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var rest2; +var rest2 = __rest(undefinedUnion, []); +var rest3; +var rest3 = __rest(nullUnion, []); +var rest4; +var rest4 = __rest(nullAndUndefinedUnion, []); +var rest5; +var rest5 = __rest(unionWithIntersection, []); diff --git a/tests/baselines/reference/restUnion2.symbols b/tests/baselines/reference/restUnion2.symbols new file mode 100644 index 00000000000..20a113a23b4 --- /dev/null +++ b/tests/baselines/reference/restUnion2.symbols @@ -0,0 +1,52 @@ +=== tests/cases/compiler/restUnion2.ts === + +declare const undefinedUnion: { n: number } | undefined; +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion2.ts, 1, 13)) +>n : Symbol(n, Decl(restUnion2.ts, 1, 31)) + +var rest2: { n: number }; +>rest2 : Symbol(rest2, Decl(restUnion2.ts, 2, 3), Decl(restUnion2.ts, 3, 5)) +>n : Symbol(n, Decl(restUnion2.ts, 2, 12)) + +var {...rest2 } = undefinedUnion; +>rest2 : Symbol(rest2, Decl(restUnion2.ts, 2, 3), Decl(restUnion2.ts, 3, 5)) +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion2.ts, 1, 13)) + + +declare const nullUnion: { n: number } | null; +>nullUnion : Symbol(nullUnion, Decl(restUnion2.ts, 6, 13)) +>n : Symbol(n, Decl(restUnion2.ts, 6, 26)) + +var rest3: { n: number }; +>rest3 : Symbol(rest3, Decl(restUnion2.ts, 7, 3), Decl(restUnion2.ts, 8, 5)) +>n : Symbol(n, Decl(restUnion2.ts, 7, 12)) + +var {...rest3 } = nullUnion; +>rest3 : Symbol(rest3, Decl(restUnion2.ts, 7, 3), Decl(restUnion2.ts, 8, 5)) +>nullUnion : Symbol(nullUnion, Decl(restUnion2.ts, 6, 13)) + + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 11, 13)) + +var rest4: { }; +>rest4 : Symbol(rest4, Decl(restUnion2.ts, 12, 3), Decl(restUnion2.ts, 13, 5)) + +var {...rest4 } = nullAndUndefinedUnion; +>rest4 : Symbol(rest4, Decl(restUnion2.ts, 12, 3), Decl(restUnion2.ts, 13, 5)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 11, 13)) + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +>unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 15, 13)) +>n : Symbol(n, Decl(restUnion2.ts, 15, 39)) +>s : Symbol(s, Decl(restUnion2.ts, 15, 55)) + +var rest5: { n: number, s: string }; +>rest5 : Symbol(rest5, Decl(restUnion2.ts, 16, 3), Decl(restUnion2.ts, 17, 5)) +>n : Symbol(n, Decl(restUnion2.ts, 16, 12)) +>s : Symbol(s, Decl(restUnion2.ts, 16, 23)) + +var {...rest5 } = unionWithIntersection; +>rest5 : Symbol(rest5, Decl(restUnion2.ts, 16, 3), Decl(restUnion2.ts, 17, 5)) +>unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 15, 13)) + diff --git a/tests/baselines/reference/restUnion2.types b/tests/baselines/reference/restUnion2.types new file mode 100644 index 00000000000..81b768777fd --- /dev/null +++ b/tests/baselines/reference/restUnion2.types @@ -0,0 +1,55 @@ +=== tests/cases/compiler/restUnion2.ts === + +declare const undefinedUnion: { n: number } | undefined; +>undefinedUnion : { n: number; } | undefined +>n : number + +var rest2: { n: number }; +>rest2 : { n: number; } +>n : number + +var {...rest2 } = undefinedUnion; +>rest2 : { n: number; } +>undefinedUnion : { n: number; } | undefined + + +declare const nullUnion: { n: number } | null; +>nullUnion : { n: number; } | null +>n : number +>null : null + +var rest3: { n: number }; +>rest3 : { n: number; } +>n : number + +var {...rest3 } = nullUnion; +>rest3 : { n: number; } +>nullUnion : { n: number; } | null + + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : null | undefined +>null : null + +var rest4: { }; +>rest4 : {} + +var {...rest4 } = nullAndUndefinedUnion; +>rest4 : {} +>nullAndUndefinedUnion : null | undefined + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null +>n : number +>s : string +>null : null + +var rest5: { n: number, s: string }; +>rest5 : { n: number; s: string; } +>n : number +>s : string + +var {...rest5 } = unionWithIntersection; +>rest5 : { n: number; s: string; } +>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null + diff --git a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt index 34356e53813..5088390f9ee 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt @@ -9,14 +9,12 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(44,17): error TS2698: Spread t tests/cases/compiler/spreadInvalidArgumentType.ts(45,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(47,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(48,17): error TS2698: Spread types may only be created from object types. -tests/cases/compiler/spreadInvalidArgumentType.ts(50,17): error TS2698: Spread types may only be created from object types. -tests/cases/compiler/spreadInvalidArgumentType.ts(51,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(56,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread types may only be created from object types. -==== tests/cases/compiler/spreadInvalidArgumentType.ts (16 errors) ==== +==== tests/cases/compiler/spreadInvalidArgumentType.ts (14 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -88,12 +86,8 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread t ~~~~~~ !!! error TS2698: Spread types may only be created from object types. - var o14 = { ...u }; // Error - ~~~~ -!!! error TS2698: Spread types may only be created from object types. - var o15 = { ...n }; // Error - ~~~~ -!!! error TS2698: Spread types may only be created from object types. + var o14 = { ...u }; // OK + var o15 = { ...n }; // OK var o16 = { ...a }; // OK diff --git a/tests/baselines/reference/spreadInvalidArgumentType.js b/tests/baselines/reference/spreadInvalidArgumentType.js index ecea599842e..26f958f224d 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.js +++ b/tests/baselines/reference/spreadInvalidArgumentType.js @@ -48,8 +48,8 @@ function f(p1: T, p2: T[]) { var o12 = { ...num }; // Error var o13 = { ...str }; // Error - var o14 = { ...u }; // Error - var o15 = { ...n }; // Error + var o14 = { ...u }; // OK + var o15 = { ...n }; // OK var o16 = { ...a }; // OK @@ -105,8 +105,8 @@ function f(p1, p2) { var o11 = __assign({}, intersection_premitive); // Error, intersection with generic type parameter var o12 = __assign({}, num); // Error var o13 = __assign({}, str); // Error - var o14 = __assign({}, u); // Error - var o15 = __assign({}, n); // Error + var o14 = __assign({}, u); // OK + var o15 = __assign({}, n); // OK var o16 = __assign({}, a); // OK var o17 = __assign({}, literal_string); // Error var o18 = __assign({}, literal_number); // Error diff --git a/tests/baselines/reference/spreadUnion2.js b/tests/baselines/reference/spreadUnion2.js new file mode 100644 index 00000000000..6c7527af9dd --- /dev/null +++ b/tests/baselines/reference/spreadUnion2.js @@ -0,0 +1,49 @@ +//// [spreadUnion2.ts] + +declare const undefinedUnion: { a: number } | undefined; +declare const nullUnion: { b: number } | null; +declare const nullAndUndefinedUnion: null | undefined; + +var o1: { a: number }; +var o1 = { ...undefinedUnion }; + +var o2: { b: number }; +var o2 = { ...nullUnion }; + +var o3: { a: number, b: number }; +var o3 = { ...undefinedUnion, ...nullUnion }; +var o3 = { ...nullUnion, ...undefinedUnion }; + +var o4: { a: number }; +var o4 = { ...undefinedUnion, ...undefinedUnion }; + +var o5: { b: number }; +var o5 = { ...nullUnion, ...nullUnion }; + +var o6: { }; +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +var o6 = { ...nullAndUndefinedUnion }; + +//// [spreadUnion2.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; +}; +var o1; +var o1 = __assign({}, undefinedUnion); +var o2; +var o2 = __assign({}, nullUnion); +var o3; +var o3 = __assign({}, undefinedUnion, nullUnion); +var o3 = __assign({}, nullUnion, undefinedUnion); +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); diff --git a/tests/baselines/reference/spreadUnion2.symbols b/tests/baselines/reference/spreadUnion2.symbols new file mode 100644 index 00000000000..cc2c194f2a6 --- /dev/null +++ b/tests/baselines/reference/spreadUnion2.symbols @@ -0,0 +1,74 @@ +=== tests/cases/compiler/spreadUnion2.ts === + +declare const undefinedUnion: { a: number } | undefined; +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) +>a : Symbol(a, Decl(spreadUnion2.ts, 1, 31)) + +declare const nullUnion: { b: number } | null; +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) +>b : Symbol(b, Decl(spreadUnion2.ts, 2, 26)) + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) + +var o1: { a: number }; +>o1 : Symbol(o1, Decl(spreadUnion2.ts, 5, 3), Decl(spreadUnion2.ts, 6, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 5, 9)) + +var o1 = { ...undefinedUnion }; +>o1 : Symbol(o1, Decl(spreadUnion2.ts, 5, 3), Decl(spreadUnion2.ts, 6, 3)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) + +var o2: { b: number }; +>o2 : Symbol(o2, Decl(spreadUnion2.ts, 8, 3), Decl(spreadUnion2.ts, 9, 3)) +>b : Symbol(b, Decl(spreadUnion2.ts, 8, 9)) + +var o2 = { ...nullUnion }; +>o2 : Symbol(o2, Decl(spreadUnion2.ts, 8, 3), Decl(spreadUnion2.ts, 9, 3)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) + +var o3: { a: number, b: number }; +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 11, 9)) +>b : Symbol(b, Decl(spreadUnion2.ts, 11, 20)) + +var o3 = { ...undefinedUnion, ...nullUnion }; +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) + +var o3 = { ...nullUnion, ...undefinedUnion }; +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) + +var o4: { a: number }; +>o4 : Symbol(o4, Decl(spreadUnion2.ts, 15, 3), Decl(spreadUnion2.ts, 16, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 15, 9)) + +var o4 = { ...undefinedUnion, ...undefinedUnion }; +>o4 : Symbol(o4, Decl(spreadUnion2.ts, 15, 3), Decl(spreadUnion2.ts, 16, 3)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) + +var o5: { b: number }; +>o5 : Symbol(o5, Decl(spreadUnion2.ts, 18, 3), Decl(spreadUnion2.ts, 19, 3)) +>b : Symbol(b, Decl(spreadUnion2.ts, 18, 9)) + +var o5 = { ...nullUnion, ...nullUnion }; +>o5 : Symbol(o5, Decl(spreadUnion2.ts, 18, 3), Decl(spreadUnion2.ts, 19, 3)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) + +var o6: { }; +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3)) + +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) + +var o6 = { ...nullAndUndefinedUnion }; +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) + diff --git a/tests/baselines/reference/spreadUnion2.types b/tests/baselines/reference/spreadUnion2.types new file mode 100644 index 00000000000..cf90381ca77 --- /dev/null +++ b/tests/baselines/reference/spreadUnion2.types @@ -0,0 +1,84 @@ +=== tests/cases/compiler/spreadUnion2.ts === + +declare const undefinedUnion: { a: number } | undefined; +>undefinedUnion : { a: number; } | undefined +>a : number + +declare const nullUnion: { b: number } | null; +>nullUnion : { b: number; } | null +>b : number +>null : null + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : null | undefined +>null : null + +var o1: { a: number }; +>o1 : { a: number; } +>a : number + +var o1 = { ...undefinedUnion }; +>o1 : { a: number; } +>{ ...undefinedUnion } : { a: number; } +>undefinedUnion : { a: number; } | undefined + +var o2: { b: number }; +>o2 : { b: number; } +>b : number + +var o2 = { ...nullUnion }; +>o2 : { b: number; } +>{ ...nullUnion } : { b: number; } +>nullUnion : { b: number; } | null + +var o3: { a: number, b: number }; +>o3 : { a: number; b: number; } +>a : number +>b : number + +var o3 = { ...undefinedUnion, ...nullUnion }; +>o3 : { a: number; b: number; } +>{ ...undefinedUnion, ...nullUnion } : { 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; } +>nullUnion : { b: number; } | null +>undefinedUnion : { a: number; } | undefined + +var o4: { a: number }; +>o4 : { a: number; } +>a : number + +var o4 = { ...undefinedUnion, ...undefinedUnion }; +>o4 : { a: number; } +>{ ...undefinedUnion, ...undefinedUnion } : { a: number; } +>undefinedUnion : { a: number; } | undefined +>undefinedUnion : { a: number; } | undefined + +var o5: { b: number }; +>o5 : { b: number; } +>b : number + +var o5 = { ...nullUnion, ...nullUnion }; +>o5 : { b: number; } +>{ ...nullUnion, ...nullUnion } : { b: number; } +>nullUnion : { b: number; } | null +>nullUnion : { b: number; } | null + +var o6: { }; +>o6 : {} + +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +>o6 : {} +>{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {} +>nullAndUndefinedUnion : null | undefined +>nullAndUndefinedUnion : null | undefined + +var o6 = { ...nullAndUndefinedUnion }; +>o6 : {} +>{ ...nullAndUndefinedUnion } : {} +>nullAndUndefinedUnion : null | undefined + diff --git a/tests/cases/compiler/restInvalidArgumentType.ts b/tests/cases/compiler/restInvalidArgumentType.ts index 7f7037bbb33..488f546e231 100644 --- a/tests/cases/compiler/restInvalidArgumentType.ts +++ b/tests/cases/compiler/restInvalidArgumentType.ts @@ -47,8 +47,8 @@ function f(p1: T, p2: T[]) { var {...r12} = num; // Error var {...r13} = str; // Error - var {...r14} = u; // Error - var {...r15} = n; // Error + var {...r14} = u; // OK + var {...r15} = n; // OK var {...r16} = a; // OK diff --git a/tests/cases/compiler/restUnion.ts b/tests/cases/compiler/restUnion.ts new file mode 100644 index 00000000000..c838b37340f --- /dev/null +++ b/tests/cases/compiler/restUnion.ts @@ -0,0 +1,14 @@ +var union: { a: number, c: boolean } | { a: string, b: string }; + +var rest1: { c: boolean } | { b: string }; +var {a, ...rest1 } = union; + + +var undefinedUnion: { n: number } | undefined; +var rest2: {}; +var {n, ...rest2 } = undefinedUnion; + + +var nullUnion: { n: number } | null; +var rest3: {}; +var {n, ...rest3 } = nullUnion; diff --git a/tests/cases/compiler/restUnion2.ts b/tests/cases/compiler/restUnion2.ts new file mode 100644 index 00000000000..83d94e03a73 --- /dev/null +++ b/tests/cases/compiler/restUnion2.ts @@ -0,0 +1,19 @@ +// @strictNullChecks: true + +declare const undefinedUnion: { n: number } | undefined; +var rest2: { n: number }; +var {...rest2 } = undefinedUnion; + + +declare const nullUnion: { n: number } | null; +var rest3: { n: number }; +var {...rest3 } = nullUnion; + + +declare const nullAndUndefinedUnion: null | undefined; +var rest4: { }; +var {...rest4 } = nullAndUndefinedUnion; + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +var rest5: { n: number, s: string }; +var {...rest5 } = unionWithIntersection; \ No newline at end of file diff --git a/tests/cases/compiler/spreadInvalidArgumentType.ts b/tests/cases/compiler/spreadInvalidArgumentType.ts index bb8f4894711..2ac6aa921f4 100644 --- a/tests/cases/compiler/spreadInvalidArgumentType.ts +++ b/tests/cases/compiler/spreadInvalidArgumentType.ts @@ -47,8 +47,8 @@ function f(p1: T, p2: T[]) { var o12 = { ...num }; // Error var o13 = { ...str }; // Error - var o14 = { ...u }; // Error - var o15 = { ...n }; // Error + var o14 = { ...u }; // OK + var o15 = { ...n }; // OK var o16 = { ...a }; // OK diff --git a/tests/cases/compiler/spreadUnion2.ts b/tests/cases/compiler/spreadUnion2.ts new file mode 100644 index 00000000000..25dba81c0df --- /dev/null +++ b/tests/cases/compiler/spreadUnion2.ts @@ -0,0 +1,25 @@ +// @strictNullChecks: true + +declare const undefinedUnion: { a: number } | undefined; +declare const nullUnion: { b: number } | null; +declare const nullAndUndefinedUnion: null | undefined; + +var o1: { a: number }; +var o1 = { ...undefinedUnion }; + +var o2: { b: number }; +var o2 = { ...nullUnion }; + +var o3: { a: number, b: number }; +var o3 = { ...undefinedUnion, ...nullUnion }; +var o3 = { ...nullUnion, ...undefinedUnion }; + +var o4: { a: number }; +var o4 = { ...undefinedUnion, ...undefinedUnion }; + +var o5: { b: number }; +var o5 = { ...nullUnion, ...nullUnion }; + +var o6: { }; +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +var o6 = { ...nullAndUndefinedUnion }; \ No newline at end of file