From 0dd1f0c00f641b98de531c165d884cfe2728927a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 10 Oct 2016 10:07:41 -0700 Subject: [PATCH] Add tests and update baselines. 1. Union/intersection tests. 2. Primitive tests. 3. Update baselines after removing errors. --- .../duplicateObjectLiteralProperty.errors.txt | 8 +- .../reference/interfaceSpread.errors.txt | 4 +- .../lastPropertyInLiteralWins.errors.txt | 8 +- .../reference/memberOverride.errors.txt | 5 +- .../reference/objectLiteralErrors.errors.txt | 5 +- ...tiesErrorFromNotUsingIdentifier.errors.txt | 8 +- tests/baselines/reference/objectSpread.js | 22 +- .../baselines/reference/objectSpread.symbols | 268 +++++++++--------- tests/baselines/reference/objectSpread.types | 43 +-- .../reference/objectSpreadIntersection.js | 79 ++++++ .../objectSpreadIntersection.symbols | 219 ++++++++++++++ .../reference/objectSpreadIntersection.types | 236 +++++++++++++++ .../reference/objectSpreadNegative.errors.txt | 76 +++-- .../reference/objectSpreadNegative.js | 56 ++-- .../baselines/reference/objectSpreadUnion.js | 52 ++++ .../reference/objectSpreadUnion.symbols | 122 ++++++++ .../reference/objectSpreadUnion.types | 131 +++++++++ .../conformance/types/spread/objectSpread.ts | 12 +- .../types/spread/objectSpreadIntersection.ts | 36 +++ .../types/spread/objectSpreadNegative.ts | 30 +- .../types/spread/objectSpreadUnion.ts | 23 ++ 21 files changed, 1199 insertions(+), 244 deletions(-) create mode 100644 tests/baselines/reference/objectSpreadIntersection.js create mode 100644 tests/baselines/reference/objectSpreadIntersection.symbols create mode 100644 tests/baselines/reference/objectSpreadIntersection.types create mode 100644 tests/baselines/reference/objectSpreadUnion.js create mode 100644 tests/baselines/reference/objectSpreadUnion.symbols create mode 100644 tests/baselines/reference/objectSpreadUnion.types create mode 100644 tests/cases/conformance/types/spread/objectSpreadIntersection.ts create mode 100644 tests/cases/conformance/types/spread/objectSpreadUnion.ts diff --git a/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt b/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt index 926a7071222..abc56a6f8fc 100644 --- a/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt +++ b/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt @@ -1,8 +1,6 @@ tests/cases/compiler/duplicateObjectLiteralProperty.ts(4,5): error TS2300: Duplicate identifier 'a'. tests/cases/compiler/duplicateObjectLiteralProperty.ts(5,5): error TS2300: Duplicate identifier '\u0061'. -tests/cases/compiler/duplicateObjectLiteralProperty.ts(5,5): error TS2698: Cannot change type of property 'a' from 'number' to 'string'. tests/cases/compiler/duplicateObjectLiteralProperty.ts(6,5): error TS2300: Duplicate identifier 'a'. -tests/cases/compiler/duplicateObjectLiteralProperty.ts(6,5): error TS2698: Cannot change type of property 'a' from 'string' to '{ c: number; }'. tests/cases/compiler/duplicateObjectLiteralProperty.ts(8,9): error TS2300: Duplicate identifier '"c"'. tests/cases/compiler/duplicateObjectLiteralProperty.ts(14,9): error TS2300: Duplicate identifier 'a'. tests/cases/compiler/duplicateObjectLiteralProperty.ts(15,9): error TS2300: Duplicate identifier 'a'. @@ -10,7 +8,7 @@ tests/cases/compiler/duplicateObjectLiteralProperty.ts(16,9): error TS1118: An o tests/cases/compiler/duplicateObjectLiteralProperty.ts(16,9): error TS2300: Duplicate identifier 'a'. -==== tests/cases/compiler/duplicateObjectLiteralProperty.ts (10 errors) ==== +==== tests/cases/compiler/duplicateObjectLiteralProperty.ts (8 errors) ==== var x = { a: 1, b: true, // OK @@ -20,13 +18,9 @@ tests/cases/compiler/duplicateObjectLiteralProperty.ts(16,9): error TS2300: Dupl \u0061: "ss", // Duplicate ~~~~~~ !!! error TS2300: Duplicate identifier '\u0061'. - ~~~~~~ -!!! error TS2698: Cannot change type of property 'a' from 'number' to 'string'. a: { ~ !!! error TS2300: Duplicate identifier 'a'. - ~ -!!! error TS2698: Cannot change type of property 'a' from 'string' to '{ c: number; }'. c: 1, "c": 56, // Duplicate ~~~ diff --git a/tests/baselines/reference/interfaceSpread.errors.txt b/tests/baselines/reference/interfaceSpread.errors.txt index 2b27c972cc8..d8556de9f93 100644 --- a/tests/baselines/reference/interfaceSpread.errors.txt +++ b/tests/baselines/reference/interfaceSpread.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/spread/interfaceSpread.ts(2,5): error TS2699: Interface declaration cannot contain a spread property. +tests/cases/conformance/types/spread/interfaceSpread.ts(2,5): error TS2697: Interface declaration cannot contain a spread property. tests/cases/conformance/types/spread/interfaceSpread.ts(7,10): error TS2339: Property 'jam' does not exist on type 'Congealed<{ jam: number; }, { peanutButter: number; }>'. tests/cases/conformance/types/spread/interfaceSpread.ts(8,10): error TS2339: Property 'peanutButter' does not exist on type 'Congealed<{ jam: number; }, { peanutButter: number; }>'. @@ -7,7 +7,7 @@ tests/cases/conformance/types/spread/interfaceSpread.ts(8,10): error TS2339: Pro interface Congealed { ...T ~~~~ -!!! error TS2699: Interface declaration cannot contain a spread property. +!!! error TS2697: Interface declaration cannot contain a spread property. ...U } diff --git a/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt b/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt index c8844f2c572..2b4a694975b 100644 --- a/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt +++ b/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt @@ -4,12 +4,10 @@ tests/cases/compiler/lastPropertyInLiteralWins.ts(7,6): error TS2345: Argument o Types of parameters 'num' and 'str' are incompatible. Type 'string' is not assignable to type 'number'. tests/cases/compiler/lastPropertyInLiteralWins.ts(9,5): error TS2300: Duplicate identifier 'thunk'. -tests/cases/compiler/lastPropertyInLiteralWins.ts(9,5): error TS2698: Cannot change type of property 'thunk' from '(str: string) => void' to '(num: number) => void'. tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2300: Duplicate identifier 'thunk'. -tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2698: Cannot change type of property 'thunk' from '(num: number) => void' to '(str: string) => void'. -==== tests/cases/compiler/lastPropertyInLiteralWins.ts (5 errors) ==== +==== tests/cases/compiler/lastPropertyInLiteralWins.ts (3 errors) ==== interface Thing { thunk: (str: string) => void; } @@ -24,8 +22,6 @@ tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2698: Cannot ch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~ !!! error TS2300: Duplicate identifier 'thunk'. - ~~~~~ -!!! error TS2698: Cannot change type of property 'thunk' from '(str: string) => void' to '(num: number) => void'. }); ~ !!! error TS2345: Argument of type '{ thunk: (num: number) => void; }' is not assignable to parameter of type 'Thing'. @@ -39,7 +35,5 @@ tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2698: Cannot ch thunk: (str: string) => {} ~~~~~ !!! error TS2300: Duplicate identifier 'thunk'. - ~~~~~ -!!! error TS2698: Cannot change type of property 'thunk' from '(num: number) => void' to '(str: string) => void'. }); \ No newline at end of file diff --git a/tests/baselines/reference/memberOverride.errors.txt b/tests/baselines/reference/memberOverride.errors.txt index 355db001505..15c4b2ad37b 100644 --- a/tests/baselines/reference/memberOverride.errors.txt +++ b/tests/baselines/reference/memberOverride.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/memberOverride.ts(5,5): error TS2300: Duplicate identifier 'a'. -tests/cases/compiler/memberOverride.ts(5,5): error TS2698: Cannot change type of property 'a' from 'string' to 'number'. -==== tests/cases/compiler/memberOverride.ts (2 errors) ==== +==== tests/cases/compiler/memberOverride.ts (1 errors) ==== // An object initialiser accepts the first definition for the same property with a different type signature // Should compile, since the second declaration of a overrides the first var x = { @@ -10,8 +9,6 @@ tests/cases/compiler/memberOverride.ts(5,5): error TS2698: Cannot change type of a: 5 ~ !!! error TS2300: Duplicate identifier 'a'. - ~ -!!! error TS2698: Cannot change type of property 'a' from 'string' to 'number'. } var n: number = x.a; \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralErrors.errors.txt b/tests/baselines/reference/objectLiteralErrors.errors.txt index f70f255df05..234ac24a8fd 100644 --- a/tests/baselines/reference/objectLiteralErrors.errors.txt +++ b/tests/baselines/reference/objectLiteralErrors.errors.txt @@ -1,7 +1,6 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(3,18): error TS2300: Duplicate identifier 'a'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(4,19): error TS2300: Duplicate identifier 'a'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(5,18): error TS2300: Duplicate identifier 'a'. -tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(5,18): error TS2698: Cannot change type of property 'a' from 'number' to 'string'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(6,21): error TS2300: Duplicate identifier 'a'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(7,19): error TS2300: Duplicate identifier 'a'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(8,18): error TS2300: Duplicate identifier ''a''. @@ -79,7 +78,7 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(45,16) tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(45,55): error TS2380: 'get' and 'set' accessor must have the same type. -==== tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts (79 errors) ==== +==== tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts (78 errors) ==== // Multiple properties with the same name var e1 = { a: 0, a: 0 }; @@ -91,8 +90,6 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(45,55) var e3 = { a: 0, a: '' }; ~ !!! error TS2300: Duplicate identifier 'a'. - ~ -!!! error TS2698: Cannot change type of property 'a' from 'number' to 'string'. var e4 = { a: true, a: false }; ~ !!! error TS2300: Duplicate identifier 'a'. diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt index cbe19cab2d2..5fa8a12e875 100644 --- a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt @@ -8,14 +8,12 @@ tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPr tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(10,10): error TS1005: ':' expected. tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(12,1): error TS1005: ':' expected. tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(15,6): error TS1005: ':' expected. -tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(16,5): error TS2698: Cannot change type of property 'a' from 'any' to 'string[]'. tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(16,6): error TS1005: ':' expected. -tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(17,5): error TS2698: Cannot change type of property 'a' from 'string[]' to 'number[]'. tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(17,6): error TS1005: ':' expected. tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts(20,17): error TS1005: ':' expected. -==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts (15 errors) ==== +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts (13 errors) ==== // errors var y = { "stringLiteral", @@ -52,13 +50,9 @@ tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPr ~ !!! error TS1005: ':' expected. a["ss"], - ~ -!!! error TS2698: Cannot change type of property 'a' from 'any' to 'string[]'. ~ !!! error TS1005: ':' expected. a[1], - ~ -!!! error TS2698: Cannot change type of property 'a' from 'string[]' to 'number[]'. ~ !!! error TS1005: ':' expected. }; diff --git a/tests/baselines/reference/objectSpread.js b/tests/baselines/reference/objectSpread.js index a59577fe9de..a09f5aa0fbb 100644 --- a/tests/baselines/reference/objectSpread.js +++ b/tests/baselines/reference/objectSpread.js @@ -35,11 +35,13 @@ let getter: { a: number, c: number } = { ...op, c: 7 } getter.a = 12; -// null and undefined are just skipped -let spreadNull: { a: number } = - { a: 7, ...null } -let spreadUndefined: { a: number } = - { a: 7, ...undefined } +// null, undefined, functions and primitives result in { } +let spreadNull = { ...null }; +let spreadUndefind = { ...undefined }; +let spreadNum = { ...12 }; +let spreadStr = { ...'foo' }; +let spreadBool = { ...false }; +let spreadFunc = { ...(function () { }) }; // methods are not enumerable class C { p = 1; m() { } } @@ -126,9 +128,13 @@ var propertyNested = __assign({ a: __assign({}, o) }); var op = { get a() { return 6; } }; var getter = __assign({}, op, { c: 7 }); getter.a = 12; -// null and undefined are just skipped -var spreadNull = __assign({ a: 7 }, null); -var spreadUndefined = __assign({ a: 7 }, undefined); +// null, undefined, functions and primitives result in { } +var spreadNull = __assign({}, null); +var spreadUndefind = __assign({}, undefined); +var spreadNum = __assign({}, 12); +var spreadStr = __assign({}, 'foo'); +var spreadBool = __assign({}, false); +var spreadFunc = __assign({}, (function () { })); // methods are not enumerable var C = (function () { function C() { diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 001c42804d2..edb0b4c2f08 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -150,220 +150,224 @@ getter.a = 12; >getter : Symbol(getter, Decl(objectSpread.ts, 32, 3)) >a : Symbol(a, Decl(objectSpread.ts, 32, 13)) -// null and undefined are just skipped -let spreadNull: { a: number } = +// null, undefined, functions and primitives result in { } +let spreadNull = { ...null }; >spreadNull : Symbol(spreadNull, Decl(objectSpread.ts, 37, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 37, 17)) - { a: 7, ...null } ->a : Symbol(a, Decl(objectSpread.ts, 38, 5)) +let spreadUndefind = { ...undefined }; +>spreadUndefind : Symbol(spreadUndefind, Decl(objectSpread.ts, 38, 3)) -let spreadUndefined: { a: number } = ->spreadUndefined : Symbol(spreadUndefined, Decl(objectSpread.ts, 39, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 39, 22)) +let spreadNum = { ...12 }; +>spreadNum : Symbol(spreadNum, Decl(objectSpread.ts, 39, 3)) - { a: 7, ...undefined } ->a : Symbol(a, Decl(objectSpread.ts, 40, 5)) +let spreadStr = { ...'foo' }; +>spreadStr : Symbol(spreadStr, Decl(objectSpread.ts, 40, 3)) + +let spreadBool = { ...false }; +>spreadBool : Symbol(spreadBool, Decl(objectSpread.ts, 41, 3)) + +let spreadFunc = { ...(function () { }) }; +>spreadFunc : Symbol(spreadFunc, Decl(objectSpread.ts, 42, 3)) // methods are not enumerable class C { p = 1; m() { } } ->C : Symbol(C, Decl(objectSpread.ts, 40, 26)) ->p : Symbol(C.p, Decl(objectSpread.ts, 43, 9)) ->m : Symbol(C.m, Decl(objectSpread.ts, 43, 16)) +>C : Symbol(C, Decl(objectSpread.ts, 42, 42)) +>p : Symbol(C.p, Decl(objectSpread.ts, 45, 9)) +>m : Symbol(C.m, Decl(objectSpread.ts, 45, 16)) let c: C = new C() ->c : Symbol(c, Decl(objectSpread.ts, 44, 3)) ->C : Symbol(C, Decl(objectSpread.ts, 40, 26)) ->C : Symbol(C, Decl(objectSpread.ts, 40, 26)) +>c : Symbol(c, Decl(objectSpread.ts, 46, 3)) +>C : Symbol(C, Decl(objectSpread.ts, 42, 42)) +>C : Symbol(C, Decl(objectSpread.ts, 42, 42)) let spreadC: { p: number } = { ...c } ->spreadC : Symbol(spreadC, Decl(objectSpread.ts, 45, 3)) ->p : Symbol(p, Decl(objectSpread.ts, 45, 14)) +>spreadC : Symbol(spreadC, Decl(objectSpread.ts, 47, 3)) +>p : Symbol(p, Decl(objectSpread.ts, 47, 14)) // own methods are enumerable let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } }; ->cplus : Symbol(cplus, Decl(objectSpread.ts, 48, 3)) ->p : Symbol(p, Decl(objectSpread.ts, 48, 12)) ->plus : Symbol(plus, Decl(objectSpread.ts, 48, 23)) ->plus : Symbol(plus, Decl(objectSpread.ts, 48, 48)) +>cplus : Symbol(cplus, Decl(objectSpread.ts, 50, 3)) +>p : Symbol(p, Decl(objectSpread.ts, 50, 12)) +>plus : Symbol(plus, Decl(objectSpread.ts, 50, 23)) +>plus : Symbol(plus, Decl(objectSpread.ts, 50, 48)) cplus.plus(); ->cplus.plus : Symbol(plus, Decl(objectSpread.ts, 48, 23)) ->cplus : Symbol(cplus, Decl(objectSpread.ts, 48, 3)) ->plus : Symbol(plus, Decl(objectSpread.ts, 48, 23)) +>cplus.plus : Symbol(plus, Decl(objectSpread.ts, 50, 23)) +>cplus : Symbol(cplus, Decl(objectSpread.ts, 50, 3)) +>plus : Symbol(plus, Decl(objectSpread.ts, 50, 23)) // new field's type conflicting with existing field is OK let changeTypeAfter: { a: string, b: string } = ->changeTypeAfter : Symbol(changeTypeAfter, Decl(objectSpread.ts, 52, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 52, 22)) ->b : Symbol(b, Decl(objectSpread.ts, 52, 33)) +>changeTypeAfter : Symbol(changeTypeAfter, Decl(objectSpread.ts, 54, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 54, 22)) +>b : Symbol(b, Decl(objectSpread.ts, 54, 33)) { ...o, a: 'wrong type?' } ->a : Symbol(a, Decl(objectSpread.ts, 53, 11)) +>a : Symbol(a, Decl(objectSpread.ts, 55, 11)) let changeTypeBefore: { a: number, b: string } = ->changeTypeBefore : Symbol(changeTypeBefore, Decl(objectSpread.ts, 54, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 54, 23)) ->b : Symbol(b, Decl(objectSpread.ts, 54, 34)) +>changeTypeBefore : Symbol(changeTypeBefore, Decl(objectSpread.ts, 56, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 56, 23)) +>b : Symbol(b, Decl(objectSpread.ts, 56, 34)) { a: 'wrong type?', ...o }; ->a : Symbol(a, Decl(objectSpread.ts, 55, 5)) +>a : Symbol(a, Decl(objectSpread.ts, 57, 5)) let changeTypeBoth: { a: string, b: number } = ->changeTypeBoth : Symbol(changeTypeBoth, Decl(objectSpread.ts, 56, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 56, 21)) ->b : Symbol(b, Decl(objectSpread.ts, 56, 32)) +>changeTypeBoth : Symbol(changeTypeBoth, Decl(objectSpread.ts, 58, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 58, 21)) +>b : Symbol(b, Decl(objectSpread.ts, 58, 32)) { ...o, ...swap }; // optional let definiteBoolean: { sn: boolean }; ->definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 60, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 60, 22)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 62, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 62, 22)) let definiteString: { sn: string }; ->definiteString : Symbol(definiteString, Decl(objectSpread.ts, 61, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 61, 21)) - -let optionalString: { sn?: string }; ->optionalString : Symbol(optionalString, Decl(objectSpread.ts, 62, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 62, 21)) - -let optionalNumber: { sn?: number }; ->optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 63, 3)) +>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 63, 3)) >sn : Symbol(sn, Decl(objectSpread.ts, 63, 21)) +let optionalString: { sn?: string }; +>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 64, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 64, 21)) + +let optionalNumber: { sn?: number }; +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 65, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 65, 21)) + let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; ->optionalUnionStops : Symbol(optionalUnionStops, Decl(objectSpread.ts, 64, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 64, 25)) +>optionalUnionStops : Symbol(optionalUnionStops, Decl(objectSpread.ts, 66, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 66, 25)) let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; ->optionalUnionDuplicates : Symbol(optionalUnionDuplicates, Decl(objectSpread.ts, 65, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 65, 30)) +>optionalUnionDuplicates : Symbol(optionalUnionDuplicates, Decl(objectSpread.ts, 67, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 67, 30)) let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; ->allOptional : Symbol(allOptional, Decl(objectSpread.ts, 66, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 66, 18)) +>allOptional : Symbol(allOptional, Decl(objectSpread.ts, 68, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 68, 18)) // computed property let computedFirst: { a: number, b: string, "before everything": number } = ->computedFirst : Symbol(computedFirst, Decl(objectSpread.ts, 69, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 69, 20)) ->b : Symbol(b, Decl(objectSpread.ts, 69, 31)) +>computedFirst : Symbol(computedFirst, Decl(objectSpread.ts, 71, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 71, 20)) +>b : Symbol(b, Decl(objectSpread.ts, 71, 31)) { ['before everything']: 12, ...o, b: 'yes' } ->'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 70, 5)) ->b : Symbol(b, Decl(objectSpread.ts, 70, 38)) +>'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 72, 5)) +>b : Symbol(b, Decl(objectSpread.ts, 72, 38)) let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = ->computedMiddle : Symbol(computedMiddle, Decl(objectSpread.ts, 71, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 71, 21)) ->b : Symbol(b, Decl(objectSpread.ts, 71, 32)) ->c : Symbol(c, Decl(objectSpread.ts, 71, 43)) +>computedMiddle : Symbol(computedMiddle, Decl(objectSpread.ts, 73, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 73, 21)) +>b : Symbol(b, Decl(objectSpread.ts, 73, 32)) +>c : Symbol(c, Decl(objectSpread.ts, 73, 43)) { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } ->'in the middle' : Symbol(['in the middle'], Decl(objectSpread.ts, 72, 11)) ->b : Symbol(b, Decl(objectSpread.ts, 72, 34)) +>'in the middle' : Symbol(['in the middle'], Decl(objectSpread.ts, 74, 11)) +>b : Symbol(b, Decl(objectSpread.ts, 74, 34)) let computedAfter: { a: number, b: string, "at the end": number } = ->computedAfter : Symbol(computedAfter, Decl(objectSpread.ts, 73, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 73, 20)) ->b : Symbol(b, Decl(objectSpread.ts, 73, 31)) +>computedAfter : Symbol(computedAfter, Decl(objectSpread.ts, 75, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 75, 20)) +>b : Symbol(b, Decl(objectSpread.ts, 75, 31)) { ...o, b: 'yeah', ['at the end']: 14 } ->b : Symbol(b, Decl(objectSpread.ts, 74, 11)) ->'at the end' : Symbol(['at the end'], Decl(objectSpread.ts, 74, 22)) +>b : Symbol(b, Decl(objectSpread.ts, 76, 11)) +>'at the end' : Symbol(['at the end'], Decl(objectSpread.ts, 76, 22)) // shortcut syntax let a = 12; ->a : Symbol(a, Decl(objectSpread.ts, 76, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 78, 3)) let shortCutted: { a: number, b: string } = { ...o, a } ->shortCutted : Symbol(shortCutted, Decl(objectSpread.ts, 77, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 77, 18)) ->b : Symbol(b, Decl(objectSpread.ts, 77, 29)) ->a : Symbol(a, Decl(objectSpread.ts, 77, 51)) +>shortCutted : Symbol(shortCutted, Decl(objectSpread.ts, 79, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 79, 18)) +>b : Symbol(b, Decl(objectSpread.ts, 79, 29)) +>a : Symbol(a, Decl(objectSpread.ts, 79, 51)) // generics function f(t: T, u: U): { id: string, ...T, ...U } { ->f : Symbol(f, Decl(objectSpread.ts, 77, 55)) ->T : Symbol(T, Decl(objectSpread.ts, 80, 11)) ->U : Symbol(U, Decl(objectSpread.ts, 80, 13)) ->t : Symbol(t, Decl(objectSpread.ts, 80, 17)) ->T : Symbol(T, Decl(objectSpread.ts, 80, 11)) ->u : Symbol(u, Decl(objectSpread.ts, 80, 22)) ->U : Symbol(U, Decl(objectSpread.ts, 80, 13)) ->id : Symbol(id, Decl(objectSpread.ts, 80, 31)) ->T : Symbol(T, Decl(objectSpread.ts, 80, 11)) ->U : Symbol(U, Decl(objectSpread.ts, 80, 13)) +>f : Symbol(f, Decl(objectSpread.ts, 79, 55)) +>T : Symbol(T, Decl(objectSpread.ts, 82, 11)) +>U : Symbol(U, Decl(objectSpread.ts, 82, 13)) +>t : Symbol(t, Decl(objectSpread.ts, 82, 17)) +>T : Symbol(T, Decl(objectSpread.ts, 82, 11)) +>u : Symbol(u, Decl(objectSpread.ts, 82, 22)) +>U : Symbol(U, Decl(objectSpread.ts, 82, 13)) +>id : Symbol(id, Decl(objectSpread.ts, 82, 31)) +>T : Symbol(T, Decl(objectSpread.ts, 82, 11)) +>U : Symbol(U, Decl(objectSpread.ts, 82, 13)) return { id: 'id', ...t, ...u }; ->id : Symbol(id, Decl(objectSpread.ts, 81, 12)) +>id : Symbol(id, Decl(objectSpread.ts, 83, 12)) } let exclusive: { id: string, a: number, b: string, c: string, d: boolean } = ->exclusive : Symbol(exclusive, Decl(objectSpread.ts, 83, 3)) ->id : Symbol(id, Decl(objectSpread.ts, 83, 16)) ->a : Symbol(a, Decl(objectSpread.ts, 83, 28)) ->b : Symbol(b, Decl(objectSpread.ts, 83, 39)) ->c : Symbol(c, Decl(objectSpread.ts, 83, 50)) ->d : Symbol(d, Decl(objectSpread.ts, 83, 61)) +>exclusive : Symbol(exclusive, Decl(objectSpread.ts, 85, 3)) +>id : Symbol(id, Decl(objectSpread.ts, 85, 16)) +>a : Symbol(a, Decl(objectSpread.ts, 85, 28)) +>b : Symbol(b, Decl(objectSpread.ts, 85, 39)) +>c : Symbol(c, Decl(objectSpread.ts, 85, 50)) +>d : Symbol(d, Decl(objectSpread.ts, 85, 61)) f({ a: 1, b: 'yes' }, { c: 'no', d: false }) ->f : Symbol(f, Decl(objectSpread.ts, 77, 55)) ->a : Symbol(a, Decl(objectSpread.ts, 84, 7)) ->b : Symbol(b, Decl(objectSpread.ts, 84, 13)) ->c : Symbol(c, Decl(objectSpread.ts, 84, 27)) ->d : Symbol(d, Decl(objectSpread.ts, 84, 36)) +>f : Symbol(f, Decl(objectSpread.ts, 79, 55)) +>a : Symbol(a, Decl(objectSpread.ts, 86, 7)) +>b : Symbol(b, Decl(objectSpread.ts, 86, 13)) +>c : Symbol(c, Decl(objectSpread.ts, 86, 27)) +>d : Symbol(d, Decl(objectSpread.ts, 86, 36)) let overlap: { id: string, a: number, b: string } = ->overlap : Symbol(overlap, Decl(objectSpread.ts, 85, 3)) ->id : Symbol(id, Decl(objectSpread.ts, 85, 14)) ->a : Symbol(a, Decl(objectSpread.ts, 85, 26)) ->b : Symbol(b, Decl(objectSpread.ts, 85, 37)) +>overlap : Symbol(overlap, Decl(objectSpread.ts, 87, 3)) +>id : Symbol(id, Decl(objectSpread.ts, 87, 14)) +>a : Symbol(a, Decl(objectSpread.ts, 87, 26)) +>b : Symbol(b, Decl(objectSpread.ts, 87, 37)) f({ a: 1 }, { a: 2, b: 'extra' }) ->f : Symbol(f, Decl(objectSpread.ts, 77, 55)) ->a : Symbol(a, Decl(objectSpread.ts, 86, 7)) ->a : Symbol(a, Decl(objectSpread.ts, 86, 17)) ->b : Symbol(b, Decl(objectSpread.ts, 86, 23)) - -let overlapConflict: { id:string, a: string } = ->overlapConflict : Symbol(overlapConflict, Decl(objectSpread.ts, 87, 3)) ->id : Symbol(id, Decl(objectSpread.ts, 87, 22)) ->a : Symbol(a, Decl(objectSpread.ts, 87, 33)) - - f({ a: 1 }, { a: 'mismatch' }) ->f : Symbol(f, Decl(objectSpread.ts, 77, 55)) +>f : Symbol(f, Decl(objectSpread.ts, 79, 55)) >a : Symbol(a, Decl(objectSpread.ts, 88, 7)) >a : Symbol(a, Decl(objectSpread.ts, 88, 17)) +>b : Symbol(b, Decl(objectSpread.ts, 88, 23)) + +let overlapConflict: { id:string, a: string } = +>overlapConflict : Symbol(overlapConflict, Decl(objectSpread.ts, 89, 3)) +>id : Symbol(id, Decl(objectSpread.ts, 89, 22)) +>a : Symbol(a, Decl(objectSpread.ts, 89, 33)) + + f({ a: 1 }, { a: 'mismatch' }) +>f : Symbol(f, Decl(objectSpread.ts, 79, 55)) +>a : Symbol(a, Decl(objectSpread.ts, 90, 7)) +>a : Symbol(a, Decl(objectSpread.ts, 90, 17)) let overwriteId: { id: boolean, a: number, c: number, d: string } = ->overwriteId : Symbol(overwriteId, Decl(objectSpread.ts, 89, 3)) ->id : Symbol(id, Decl(objectSpread.ts, 89, 18)) ->a : Symbol(a, Decl(objectSpread.ts, 89, 31)) ->c : Symbol(c, Decl(objectSpread.ts, 89, 42)) ->d : Symbol(d, Decl(objectSpread.ts, 89, 53)) +>overwriteId : Symbol(overwriteId, Decl(objectSpread.ts, 91, 3)) +>id : Symbol(id, Decl(objectSpread.ts, 91, 18)) +>a : Symbol(a, Decl(objectSpread.ts, 91, 31)) +>c : Symbol(c, Decl(objectSpread.ts, 91, 42)) +>d : Symbol(d, Decl(objectSpread.ts, 91, 53)) f({ a: 1, id: true }, { c: 1, d: 'no' }) ->f : Symbol(f, Decl(objectSpread.ts, 77, 55)) ->a : Symbol(a, Decl(objectSpread.ts, 90, 7)) ->id : Symbol(id, Decl(objectSpread.ts, 90, 13)) ->c : Symbol(c, Decl(objectSpread.ts, 90, 27)) ->d : Symbol(d, Decl(objectSpread.ts, 90, 33)) +>f : Symbol(f, Decl(objectSpread.ts, 79, 55)) +>a : Symbol(a, Decl(objectSpread.ts, 92, 7)) +>id : Symbol(id, Decl(objectSpread.ts, 92, 13)) +>c : Symbol(c, Decl(objectSpread.ts, 92, 27)) +>d : Symbol(d, Decl(objectSpread.ts, 92, 33)) class D { m() { }; q = 2; } ->D : Symbol(D, Decl(objectSpread.ts, 90, 44)) ->m : Symbol(D.m, Decl(objectSpread.ts, 92, 9)) ->q : Symbol(D.q, Decl(objectSpread.ts, 92, 18)) +>D : Symbol(D, Decl(objectSpread.ts, 92, 44)) +>m : Symbol(D.m, Decl(objectSpread.ts, 94, 9)) +>q : Symbol(D.q, Decl(objectSpread.ts, 94, 18)) let classesAreWrong: { id: string, ...C, ...D } = ->classesAreWrong : Symbol(classesAreWrong, Decl(objectSpread.ts, 93, 3)) ->id : Symbol(id, Decl(objectSpread.ts, 93, 22)) ->C : Symbol(C, Decl(objectSpread.ts, 40, 26)) ->D : Symbol(D, Decl(objectSpread.ts, 90, 44)) +>classesAreWrong : Symbol(classesAreWrong, Decl(objectSpread.ts, 95, 3)) +>id : Symbol(id, Decl(objectSpread.ts, 95, 22)) +>C : Symbol(C, Decl(objectSpread.ts, 42, 42)) +>D : Symbol(D, Decl(objectSpread.ts, 92, 44)) f(new C(), new D()) ->f : Symbol(f, Decl(objectSpread.ts, 77, 55)) ->C : Symbol(C, Decl(objectSpread.ts, 40, 26)) ->D : Symbol(D, Decl(objectSpread.ts, 90, 44)) +>f : Symbol(f, Decl(objectSpread.ts, 79, 55)) +>C : Symbol(C, Decl(objectSpread.ts, 42, 42)) +>D : Symbol(D, Decl(objectSpread.ts, 92, 44)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index 86d04eb4588..2b13af1d3d6 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -223,27 +223,36 @@ getter.a = 12; >a : number >12 : 12 -// null and undefined are just skipped -let spreadNull: { a: number } = ->spreadNull : { a: number; } ->a : number - - { a: 7, ...null } ->{ a: 7, ...null } : { a: number; } ->a : number ->7 : 7 +// null, undefined, functions and primitives result in { } +let spreadNull = { ...null }; +>spreadNull : {} +>{ ...null } : {} >null : null -let spreadUndefined: { a: number } = ->spreadUndefined : { a: number; } ->a : number - - { a: 7, ...undefined } ->{ a: 7, ...undefined } : { a: number; } ->a : number ->7 : 7 +let spreadUndefind = { ...undefined }; +>spreadUndefind : {} +>{ ...undefined } : {} >undefined : any +let spreadNum = { ...12 }; +>spreadNum : {} +>{ ...12 } : {} + +let spreadStr = { ...'foo' }; +>spreadStr : {} +>{ ...'foo' } : {} + +let spreadBool = { ...false }; +>spreadBool : {} +>{ ...false } : {} +>false : false + +let spreadFunc = { ...(function () { }) }; +>spreadFunc : {} +>{ ...(function () { }) } : {} +>(function () { }) : () => void +>function () { } : () => void + // methods are not enumerable class C { p = 1; m() { } } >C : C diff --git a/tests/baselines/reference/objectSpreadIntersection.js b/tests/baselines/reference/objectSpreadIntersection.js new file mode 100644 index 00000000000..cb93c547963 --- /dev/null +++ b/tests/baselines/reference/objectSpreadIntersection.js @@ -0,0 +1,79 @@ +//// [objectSpreadIntersection.ts] +function iteratedUnionIntersection(t: T, u: U, v: V): void { + let tu: T | U; + let uv: U & V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: ({ id: string, ...T, ...U } & { id: string, ...T, ...V }) | ({ id: string, ...U } & { id: string, ...U, ...V }); + let assignable: { id: string, ...(T | U), ...(U & V) } = result; +} +// concrete types work +interface A1 { a: number } +interface A2 { a: string } +let a12: A1 & A2; +let result = { ...a12 }; +let sn: number & string = result.a; +let assignable: { ...(A1 & A2) } = result; + +function tripleIntersection(t: T, u: U, v: V): void { + let tuv: T & U & V; + let result = { id: 'foo', ...tuv }; + let expected: { id: string, ...T } & { id: string, ...U } & { id: string, ...V } = result; + let assignable: { id: string, ...(T & U & V) } = result; +} +function iteratedDoubleIntersection(t: T, u: U, v: V): void { + let tu: T & U; + let uv: U & V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: { id: string, ...T, ...U } & { id: string, ...T, ...V } & { id: string, ...U } & { id: string, ...U, ...V }; + let assignable: { id: string, ...(T & U), ...(U & V) } = result; +} +function iteratedIntersectionUnion(t: T, u: U, v: V): void { + let tu: T & U; + let uv: U | V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: ({ id: string, ...T, ...U } & { id: string, ...U }) | ({ id: string, ...T, ...V } & { id: string, ...U, ...V }); + let assignable: { id: string, ...(T & U), ...(U | V) } = result; +} + + + +//// [objectSpreadIntersection.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 iteratedUnionIntersection(t, u, v) { + var tu; + var uv; + var result = __assign({ id: 'bar' }, tu, uv); + var expected; + var assignable = result; +} +var a12; +var result = __assign({}, a12); +var sn = result.a; +var assignable = result; +function tripleIntersection(t, u, v) { + var tuv; + var result = __assign({ id: 'foo' }, tuv); + var expected = result; + var assignable = result; +} +function iteratedDoubleIntersection(t, u, v) { + var tu; + var uv; + var result = __assign({ id: 'bar' }, tu, uv); + var expected; + var assignable = result; +} +function iteratedIntersectionUnion(t, u, v) { + var tu; + var uv; + var result = __assign({ id: 'bar' }, tu, uv); + var expected; + var assignable = result; +} diff --git a/tests/baselines/reference/objectSpreadIntersection.symbols b/tests/baselines/reference/objectSpreadIntersection.symbols new file mode 100644 index 00000000000..f45b04a20a5 --- /dev/null +++ b/tests/baselines/reference/objectSpreadIntersection.symbols @@ -0,0 +1,219 @@ +=== tests/cases/conformance/types/spread/objectSpreadIntersection.ts === +function iteratedUnionIntersection(t: T, u: U, v: V): void { +>iteratedUnionIntersection : Symbol(iteratedUnionIntersection, Decl(objectSpreadIntersection.ts, 0, 0)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 0, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 0, 40)) +>t : Symbol(t, Decl(objectSpreadIntersection.ts, 0, 44)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 0, 35)) +>u : Symbol(u, Decl(objectSpreadIntersection.ts, 0, 49)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>v : Symbol(v, Decl(objectSpreadIntersection.ts, 0, 55)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 0, 40)) + + let tu: T | U; +>tu : Symbol(tu, Decl(objectSpreadIntersection.ts, 1, 7)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 0, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) + + let uv: U & V; +>uv : Symbol(uv, Decl(objectSpreadIntersection.ts, 2, 7)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 0, 40)) + + let result = { id: 'bar', ...tu, ...uv }; +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 3, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 3, 18)) + + let expected: ({ id: string, ...T, ...U } & { id: string, ...T, ...V }) | ({ id: string, ...U } & { id: string, ...U, ...V }); +>expected : Symbol(expected, Decl(objectSpreadIntersection.ts, 4, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 4, 20)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 0, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 4, 49)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 0, 35)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 0, 40)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 4, 80)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 4, 103)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 0, 40)) + + let assignable: { id: string, ...(T | U), ...(U & V) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadIntersection.ts, 5, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 5, 21)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 0, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 0, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 0, 40)) +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 3, 7)) +} +// concrete types work +interface A1 { a: number } +>A1 : Symbol(A1, Decl(objectSpreadIntersection.ts, 6, 1)) +>a : Symbol(A1.a, Decl(objectSpreadIntersection.ts, 8, 14)) + +interface A2 { a: string } +>A2 : Symbol(A2, Decl(objectSpreadIntersection.ts, 8, 26)) +>a : Symbol(A2.a, Decl(objectSpreadIntersection.ts, 9, 14)) + +let a12: A1 & A2; +>a12 : Symbol(a12, Decl(objectSpreadIntersection.ts, 10, 3)) +>A1 : Symbol(A1, Decl(objectSpreadIntersection.ts, 6, 1)) +>A2 : Symbol(A2, Decl(objectSpreadIntersection.ts, 8, 26)) + +let result = { ...a12 }; +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 11, 3)) + +let sn: number & string = result.a; +>sn : Symbol(sn, Decl(objectSpreadIntersection.ts, 12, 3)) +>result.a : Symbol(a, Decl(objectSpreadIntersection.ts, 8, 14), Decl(objectSpreadIntersection.ts, 9, 14)) +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 11, 3)) +>a : Symbol(a, Decl(objectSpreadIntersection.ts, 8, 14), Decl(objectSpreadIntersection.ts, 9, 14)) + +let assignable: { ...(A1 & A2) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadIntersection.ts, 13, 3)) +>A1 : Symbol(A1, Decl(objectSpreadIntersection.ts, 6, 1)) +>A2 : Symbol(A2, Decl(objectSpreadIntersection.ts, 8, 26)) +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 11, 3)) + +function tripleIntersection(t: T, u: U, v: V): void { +>tripleIntersection : Symbol(tripleIntersection, Decl(objectSpreadIntersection.ts, 13, 42)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 15, 28)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 15, 30)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 15, 33)) +>t : Symbol(t, Decl(objectSpreadIntersection.ts, 15, 37)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 15, 28)) +>u : Symbol(u, Decl(objectSpreadIntersection.ts, 15, 42)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 15, 30)) +>v : Symbol(v, Decl(objectSpreadIntersection.ts, 15, 48)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 15, 33)) + + let tuv: T & U & V; +>tuv : Symbol(tuv, Decl(objectSpreadIntersection.ts, 16, 7)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 15, 28)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 15, 30)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 15, 33)) + + let result = { id: 'foo', ...tuv }; +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 17, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 17, 18)) + + let expected: { id: string, ...T } & { id: string, ...U } & { id: string, ...V } = result; +>expected : Symbol(expected, Decl(objectSpreadIntersection.ts, 18, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 18, 19)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 15, 28)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 18, 42)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 15, 30)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 18, 65)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 15, 33)) +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 17, 7)) + + let assignable: { id: string, ...(T & U & V) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadIntersection.ts, 19, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 19, 21)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 15, 28)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 15, 30)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 15, 33)) +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 17, 7)) +} +function iteratedDoubleIntersection(t: T, u: U, v: V): void { +>iteratedDoubleIntersection : Symbol(iteratedDoubleIntersection, Decl(objectSpreadIntersection.ts, 20, 1)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 21, 36)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 21, 41)) +>t : Symbol(t, Decl(objectSpreadIntersection.ts, 21, 45)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 21, 36)) +>u : Symbol(u, Decl(objectSpreadIntersection.ts, 21, 50)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>v : Symbol(v, Decl(objectSpreadIntersection.ts, 21, 56)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 21, 41)) + + let tu: T & U; +>tu : Symbol(tu, Decl(objectSpreadIntersection.ts, 22, 7)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 21, 36)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) + + let uv: U & V; +>uv : Symbol(uv, Decl(objectSpreadIntersection.ts, 23, 7)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 21, 41)) + + let result = { id: 'bar', ...tu, ...uv }; +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 24, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 24, 18)) + + let expected: { id: string, ...T, ...U } & { id: string, ...T, ...V } & { id: string, ...U } & { id: string, ...U, ...V }; +>expected : Symbol(expected, Decl(objectSpreadIntersection.ts, 25, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 25, 19)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 21, 36)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 25, 48)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 21, 36)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 21, 41)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 25, 77)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 25, 100)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 21, 41)) + + let assignable: { id: string, ...(T & U), ...(U & V) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadIntersection.ts, 26, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 26, 21)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 21, 36)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 21, 38)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 21, 41)) +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 24, 7)) +} +function iteratedIntersectionUnion(t: T, u: U, v: V): void { +>iteratedIntersectionUnion : Symbol(iteratedIntersectionUnion, Decl(objectSpreadIntersection.ts, 27, 1)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 28, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 28, 40)) +>t : Symbol(t, Decl(objectSpreadIntersection.ts, 28, 44)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 28, 35)) +>u : Symbol(u, Decl(objectSpreadIntersection.ts, 28, 49)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>v : Symbol(v, Decl(objectSpreadIntersection.ts, 28, 55)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 28, 40)) + + let tu: T & U; +>tu : Symbol(tu, Decl(objectSpreadIntersection.ts, 29, 7)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 28, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) + + let uv: U | V; +>uv : Symbol(uv, Decl(objectSpreadIntersection.ts, 30, 7)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 28, 40)) + + let result = { id: 'bar', ...tu, ...uv }; +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 31, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 31, 18)) + + let expected: ({ id: string, ...T, ...U } & { id: string, ...U }) | ({ id: string, ...T, ...V } & { id: string, ...U, ...V }); +>expected : Symbol(expected, Decl(objectSpreadIntersection.ts, 32, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 32, 20)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 28, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 32, 49)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 32, 74)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 28, 35)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 28, 40)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 32, 103)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 28, 40)) + + let assignable: { id: string, ...(T & U), ...(U | V) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadIntersection.ts, 33, 7)) +>id : Symbol(id, Decl(objectSpreadIntersection.ts, 33, 21)) +>T : Symbol(T, Decl(objectSpreadIntersection.ts, 28, 35)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>U : Symbol(U, Decl(objectSpreadIntersection.ts, 28, 37)) +>V : Symbol(V, Decl(objectSpreadIntersection.ts, 28, 40)) +>result : Symbol(result, Decl(objectSpreadIntersection.ts, 31, 7)) +} + + diff --git a/tests/baselines/reference/objectSpreadIntersection.types b/tests/baselines/reference/objectSpreadIntersection.types new file mode 100644 index 00000000000..7700d8aa384 --- /dev/null +++ b/tests/baselines/reference/objectSpreadIntersection.types @@ -0,0 +1,236 @@ +=== tests/cases/conformance/types/spread/objectSpreadIntersection.ts === +function iteratedUnionIntersection(t: T, u: U, v: V): void { +>iteratedUnionIntersection : (t: T, u: U, v: V) => void +>T : T +>U : U +>V : V +>t : T +>T : T +>u : U +>U : U +>v : V +>V : V + + let tu: T | U; +>tu : T | U +>T : T +>U : U + + let uv: U & V; +>uv : U & V +>U : U +>V : V + + let result = { id: 'bar', ...tu, ...uv }; +>result : ({ id: string; ...T; ...U } | { id: string; ...U }) & ({ id: string; ...T; ...V } | { id: string; ...U; ...V }) +>{ id: 'bar', ...tu, ...uv } : ({ id: string; ...T; ...U } | { id: string; ...U }) & ({ id: string; ...T; ...V } | { id: string; ...U; ...V }) +>id : string +>'bar' : "bar" +>tu : any +>uv : any + + let expected: ({ id: string, ...T, ...U } & { id: string, ...T, ...V }) | ({ id: string, ...U } & { id: string, ...U, ...V }); +>expected : ({ id: string; ...T; ...U } & { id: string; ...T; ...V }) | ({ id: string; ...U } & { id: string; ...U; ...V }) +>id : string +>T : T +>U : U +>id : string +>T : T +>V : V +>id : string +>U : U +>id : string +>U : U +>V : V + + let assignable: { id: string, ...(T | U), ...(U & V) } = result; +>assignable : ({ id: string; ...T; ...U } | { id: string; ...U }) & ({ id: string; ...T; ...V } | { id: string; ...U; ...V }) +>id : string +>T : T +>U : U +>U : U +>V : V +>result : ({ id: string; ...T; ...U } | { id: string; ...U }) & ({ id: string; ...T; ...V } | { id: string; ...U; ...V }) +} +// concrete types work +interface A1 { a: number } +>A1 : A1 +>a : number + +interface A2 { a: string } +>A2 : A2 +>a : string + +let a12: A1 & A2; +>a12 : A1 & A2 +>A1 : A1 +>A2 : A2 + +let result = { ...a12 }; +>result : { a: number; } & { a: string; } +>{ ...a12 } : { a: number; } & { a: string; } +>a12 : any + +let sn: number & string = result.a; +>sn : number & string +>result.a : number & string +>result : { a: number; } & { a: string; } +>a : number & string + +let assignable: { ...(A1 & A2) } = result; +>assignable : { a: number; } & { a: string; } +>A1 : A1 +>A2 : A2 +>result : { a: number; } & { a: string; } + +function tripleIntersection(t: T, u: U, v: V): void { +>tripleIntersection : (t: T, u: U, v: V) => void +>T : T +>U : U +>V : V +>t : T +>T : T +>u : U +>U : U +>v : V +>V : V + + let tuv: T & U & V; +>tuv : T & U & V +>T : T +>U : U +>V : V + + let result = { id: 'foo', ...tuv }; +>result : { id: string; ...T } & { id: string; ...U } & { id: string; ...V } +>{ id: 'foo', ...tuv } : { id: string; ...T } & { id: string; ...U } & { id: string; ...V } +>id : string +>'foo' : "foo" +>tuv : any + + let expected: { id: string, ...T } & { id: string, ...U } & { id: string, ...V } = result; +>expected : { id: string; ...T } & { id: string; ...U } & { id: string; ...V } +>id : string +>T : T +>id : string +>U : U +>id : string +>V : V +>result : { id: string; ...T } & { id: string; ...U } & { id: string; ...V } + + let assignable: { id: string, ...(T & U & V) } = result; +>assignable : { id: string; ...T } & { id: string; ...U } & { id: string; ...V } +>id : string +>T : T +>U : U +>V : V +>result : { id: string; ...T } & { id: string; ...U } & { id: string; ...V } +} +function iteratedDoubleIntersection(t: T, u: U, v: V): void { +>iteratedDoubleIntersection : (t: T, u: U, v: V) => void +>T : T +>U : U +>V : V +>t : T +>T : T +>u : U +>U : U +>v : V +>V : V + + let tu: T & U; +>tu : T & U +>T : T +>U : U + + let uv: U & V; +>uv : U & V +>U : U +>V : V + + let result = { id: 'bar', ...tu, ...uv }; +>result : { id: string; ...T; ...U } & { id: string; ...U } & { id: string; ...T; ...V } & { id: string; ...U; ...V } +>{ id: 'bar', ...tu, ...uv } : { id: string; ...T; ...U } & { id: string; ...U } & { id: string; ...T; ...V } & { id: string; ...U; ...V } +>id : string +>'bar' : "bar" +>tu : any +>uv : any + + let expected: { id: string, ...T, ...U } & { id: string, ...T, ...V } & { id: string, ...U } & { id: string, ...U, ...V }; +>expected : { id: string; ...T; ...U } & { id: string; ...T; ...V } & { id: string; ...U } & { id: string; ...U; ...V } +>id : string +>T : T +>U : U +>id : string +>T : T +>V : V +>id : string +>U : U +>id : string +>U : U +>V : V + + let assignable: { id: string, ...(T & U), ...(U & V) } = result; +>assignable : { id: string; ...T; ...U } & { id: string; ...U } & { id: string; ...T; ...V } & { id: string; ...U; ...V } +>id : string +>T : T +>U : U +>U : U +>V : V +>result : { id: string; ...T; ...U } & { id: string; ...U } & { id: string; ...T; ...V } & { id: string; ...U; ...V } +} +function iteratedIntersectionUnion(t: T, u: U, v: V): void { +>iteratedIntersectionUnion : (t: T, u: U, v: V) => void +>T : T +>U : U +>V : V +>t : T +>T : T +>u : U +>U : U +>v : V +>V : V + + let tu: T & U; +>tu : T & U +>T : T +>U : U + + let uv: U | V; +>uv : U | V +>U : U +>V : V + + let result = { id: 'bar', ...tu, ...uv }; +>result : ({ id: string; ...T; ...U } & { id: string; ...U }) | ({ id: string; ...T; ...V } & { id: string; ...U; ...V }) +>{ id: 'bar', ...tu, ...uv } : ({ id: string; ...T; ...U } & { id: string; ...U }) | ({ id: string; ...T; ...V } & { id: string; ...U; ...V }) +>id : string +>'bar' : "bar" +>tu : any +>uv : any + + let expected: ({ id: string, ...T, ...U } & { id: string, ...U }) | ({ id: string, ...T, ...V } & { id: string, ...U, ...V }); +>expected : ({ id: string; ...T; ...U } & { id: string; ...U }) | ({ id: string; ...T; ...V } & { id: string; ...U; ...V }) +>id : string +>T : T +>U : U +>id : string +>U : U +>id : string +>T : T +>V : V +>id : string +>U : U +>V : V + + let assignable: { id: string, ...(T & U), ...(U | V) } = result; +>assignable : ({ id: string; ...T; ...U } & { id: string; ...U }) | ({ id: string; ...T; ...V } & { id: string; ...U; ...V }) +>id : string +>T : T +>U : U +>U : U +>V : V +>result : ({ id: string; ...T; ...U } & { id: string; ...U }) | ({ id: string; ...T; ...V } & { id: string; ...U; ...V }) +} + + diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index 38e564c3b5d..84fb1cc4a76 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -5,19 +5,23 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(20,5): error TS2322 Property 'b' is missing in type '{ s: string; }'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(22,1): error TS2322: Type 'Bool' is not assignable to type '{ s: string; b: boolean; }'. Property 's' is missing in type 'Bool'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,15): error TS2697: Spread properties must be identifiers, property accesses, or object literals. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(26,15): error TS2697: Spread properties must be identifiers, property accesses, or object literals. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(29,36): error TS2300: Duplicate identifier 'b'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(29,53): error TS2300: Duplicate identifier 'b'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(34,12): error TS2339: Property 'b' does not exist on type '{}'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(40,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(43,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ x: number; }' has no compatible call signatures. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(44,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(47,39): error TS2697: Spread properties must be identifiers, property accesses, or object literals. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(51,12): error TS2322: Type '{ ...U }' is not assignable to type 'U'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,36): error TS2300: Duplicate identifier 'b'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,53): error TS2300: Duplicate identifier 'b'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(30,12): error TS2339: Property 'null' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(32,17): error TS2339: Property 'undefined' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(36,11): error TS2339: Property 'toFixed' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(38,11): error TS2339: Property 'toFixed' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(40,11): error TS2339: Property 'length' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(41,11): error TS2339: Property 'charAt' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(45,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(49,12): error TS2339: Property 'b' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(55,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(58,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ x: number; }' has no compatible call signatures. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(59,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(63,12): error TS2322: Type '{ ...U }' is not assignable to type 'U'. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (14 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (18 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -27,8 +31,8 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(51,12): error TS232 class PublicX { public x: number; } - let o3: { ...PublicX, ...PrivateOptionalX }; - let sn: number = o3.x; // error, x is private + let o2: { ...PublicX, ...PrivateOptionalX }; + let sn: number = o2.x; // error, x is private ~ !!! error TS2339: Property 'x' does not exist on type '{}'. let optionalString: { sn?: string }; @@ -52,14 +56,6 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(51,12): error TS232 !!! error TS2322: Type 'Bool' is not assignable to type '{ s: string; b: boolean; }'. !!! error TS2322: Property 's' is missing in type 'Bool'. - // expressions are not allowed - let o1 = { ...1 + 1 }; - ~~~~~ -!!! error TS2697: Spread properties must be identifiers, property accesses, or object literals. - let o2 = { ...(1 + 1) }; - ~~~~~~~ -!!! error TS2697: Spread properties must be identifiers, property accesses, or object literals. - // literal repeats are not allowed, but spread repeats are fine let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } ~ @@ -68,6 +64,39 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(51,12): error TS232 !!! error TS2300: Duplicate identifier 'b'. let duplicatedSpread = { ...o, ...o } + // null and undefined are just skipped + let spreadNull = { ...null } + spreadNull.null; + ~~~~ +!!! error TS2339: Property 'null' does not exist on type '{}'. + let spreadUndefined = { ...undefined } + spreadUndefined.undefined; + ~~~~~~~~~ +!!! error TS2339: Property 'undefined' does not exist on type '{}'. + + // primitives and functions are skipped + let spreadNum = { ...12 }; + spreadNum.toFixed(); // error, no methods from number + ~~~~~~~ +!!! error TS2339: Property 'toFixed' does not exist on type '{}'. + let spreadSum = { ...1 + 1 }; + spreadSum.toFixed(); // error, no methods from number + ~~~~~~~ +!!! error TS2339: Property 'toFixed' does not exist on type '{}'. + let spreadStr = { ...'foo' }; + spreadStr.length; // error, no 'length' + ~~~~~~ +!!! error TS2339: Property 'length' does not exist on type '{}'. + spreadStr.charAt(1); // error, no methods either + ~~~~~~ +!!! error TS2339: Property 'charAt' does not exist on type '{}'. + let spreadBool = { ...true }; + spreadBool.valueOf(); // error, what were you thinking? + let spreadFunc = { ...function () { } } + spreadFunc(); // error, no call signature + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. + // write-only properties get skipped let setterOnly = { ...{ set b (bad: number) { } } }; setterOnly.b = 12; // error, 'b' does not exist @@ -90,11 +119,6 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(51,12): error TS232 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. - let publicx: PublicX; - let callableSpread = { ...publicx, ...(n => n + 1) }; // error, can't spread functions - ~~~~~~~~~~~~ -!!! error TS2697: Spread properties must be identifiers, property accesses, or object literals. - // { ...U } is not assignable to U function override(initial: U, override: U): U { return { ...initial, ...override }; diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index 6874380599b..452ec457e9a 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -8,8 +8,8 @@ class PrivateOptionalX { class PublicX { public x: number; } -let o3: { ...PublicX, ...PrivateOptionalX }; -let sn: number = o3.x; // error, x is private +let o2: { ...PublicX, ...PrivateOptionalX }; +let sn: number = o2.x; // error, x is private let optionalString: { sn?: string }; let optionalNumber: { sn?: number }; let allOptional: { sn: string | number } = { ...optionalString, ...optionalNumber }; @@ -22,14 +22,29 @@ let spread: { ...Bool, ...Str } = { s: 'foo' }; // error, missing 'b' let b: Bool; spread = b; // error, missing 's' -// expressions are not allowed -let o1 = { ...1 + 1 }; -let o2 = { ...(1 + 1) }; - // literal repeats are not allowed, but spread repeats are fine let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } let duplicatedSpread = { ...o, ...o } +// null and undefined are just skipped +let spreadNull = { ...null } +spreadNull.null; +let spreadUndefined = { ...undefined } +spreadUndefined.undefined; + +// primitives and functions are skipped +let spreadNum = { ...12 }; +spreadNum.toFixed(); // error, no methods from number +let spreadSum = { ...1 + 1 }; +spreadSum.toFixed(); // error, no methods from number +let spreadStr = { ...'foo' }; +spreadStr.length; // error, no 'length' +spreadStr.charAt(1); // error, no methods either +let spreadBool = { ...true }; +spreadBool.valueOf(); // error, what were you thinking? +let spreadFunc = { ...function () { } } +spreadFunc(); // error, no call signature + // write-only properties get skipped let setterOnly = { ...{ set b (bad: number) { } } }; setterOnly.b = 12; // error, 'b' does not exist @@ -44,9 +59,6 @@ let callableConstructableSpread: { ...PublicX, (n: number): number, new (p: numb callableConstructableSpread(12); // error, no call signature new callableConstructableSpread(12); // error, no construct signature -let publicx: PublicX; -let callableSpread = { ...publicx, ...(n => n + 1) }; // error, can't spread functions - // { ...U } is not assignable to U function override(initial: U, override: U): U { return { ...initial, ...override }; @@ -74,8 +86,8 @@ var PublicX = (function () { } return PublicX; }()); -var o3; -var sn = o3.x; // error, x is private +var o2; +var sn = o2.x; // error, x is private var optionalString; var optionalNumber; var allOptional = __assign({}, optionalString, optionalNumber); @@ -84,12 +96,26 @@ var allOptional = __assign({}, optionalString, optionalNumber); var spread = { s: 'foo' }; // error, missing 'b' var b; spread = b; // error, missing 's' -// expressions are not allowed -var o1 = __assign({}, 1 + 1); -var o2 = __assign({}, (1 + 1)); // literal repeats are not allowed, but spread repeats are fine var duplicated = __assign({ b: 'bad' }, o, { b: 'bad' }, o2, { b: 'bad' }); var duplicatedSpread = __assign({}, o, o); +// null and undefined are just skipped +var spreadNull = __assign({}, null); +spreadNull.null; +var spreadUndefined = __assign({}, undefined); +spreadUndefined.undefined; +// primitives and functions are skipped +var spreadNum = __assign({}, 12); +spreadNum.toFixed(); // error, no methods from number +var spreadSum = __assign({}, 1 + 1); +spreadSum.toFixed(); // error, no methods from number +var spreadStr = __assign({}, 'foo'); +spreadStr.length; // error, no 'length' +spreadStr.charAt(1); // error, no methods either +var spreadBool = __assign({}, true); +spreadBool.valueOf(); // error, what were you thinking? +var spreadFunc = __assign({}, function () { }); +spreadFunc(); // error, no call signature // write-only properties get skipped var setterOnly = __assign({ set b(bad: number) { } }); setterOnly.b = 12; // error, 'b' does not exist @@ -107,8 +133,6 @@ spreadC.m(); // error 'm' is not in '{ ... c }' var callableConstructableSpread; callableConstructableSpread(12); // error, no call signature new callableConstructableSpread(12); // error, no construct signature -var publicx; -var callableSpread = __assign({}, publicx, (function (n) { return n + 1; })); // error, can't spread functions // { ...U } is not assignable to U function override(initial, override) { return __assign({}, initial, override); diff --git a/tests/baselines/reference/objectSpreadUnion.js b/tests/baselines/reference/objectSpreadUnion.js new file mode 100644 index 00000000000..500b8a5ddc7 --- /dev/null +++ b/tests/baselines/reference/objectSpreadUnion.js @@ -0,0 +1,52 @@ +//// [objectSpreadUnion.ts] +// concrete types work +interface A1 { a: number } +interface A2 { a: string } +let a12: A1 | A2; +let result = { ...a12 }; +let sn: number | string = result.a; +let assignable: { ...(A1 | A2) } = result; + +function tripleUnion(t: T, u: U, v: V): void { + let tuv: T | U | V; + let result = { id: 'foo', ...tuv }; + let expected: { id: string, ...T } | { id: string, ...U } | { id: string, ...V } = result; + let assignable: { id: string, ...(T | U | V) } = result; +} +function iteratedDoubleUnion(t: T, u: U, v: V): void { + let tu: T | U; + let uv: U | V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: { id: string, ...T, ...U } | { id: string, ...T, ...V } | { id: string, ...U } | { id: string, ...U, ...V }; + let assignable: { id: string, ...(T | U), ...(U | V) } = result; +} + + + + +//// [objectSpreadUnion.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 a12; +var result = __assign({}, a12); +var sn = result.a; +var assignable = result; +function tripleUnion(t, u, v) { + var tuv; + var result = __assign({ id: 'foo' }, tuv); + var expected = result; + var assignable = result; +} +function iteratedDoubleUnion(t, u, v) { + var tu; + var uv; + var result = __assign({ id: 'bar' }, tu, uv); + var expected; + var assignable = result; +} diff --git a/tests/baselines/reference/objectSpreadUnion.symbols b/tests/baselines/reference/objectSpreadUnion.symbols new file mode 100644 index 00000000000..eea9e65185d --- /dev/null +++ b/tests/baselines/reference/objectSpreadUnion.symbols @@ -0,0 +1,122 @@ +=== tests/cases/conformance/types/spread/objectSpreadUnion.ts === +// concrete types work +interface A1 { a: number } +>A1 : Symbol(A1, Decl(objectSpreadUnion.ts, 0, 0)) +>a : Symbol(A1.a, Decl(objectSpreadUnion.ts, 1, 14)) + +interface A2 { a: string } +>A2 : Symbol(A2, Decl(objectSpreadUnion.ts, 1, 26)) +>a : Symbol(A2.a, Decl(objectSpreadUnion.ts, 2, 14)) + +let a12: A1 | A2; +>a12 : Symbol(a12, Decl(objectSpreadUnion.ts, 3, 3)) +>A1 : Symbol(A1, Decl(objectSpreadUnion.ts, 0, 0)) +>A2 : Symbol(A2, Decl(objectSpreadUnion.ts, 1, 26)) + +let result = { ...a12 }; +>result : Symbol(result, Decl(objectSpreadUnion.ts, 4, 3)) + +let sn: number | string = result.a; +>sn : Symbol(sn, Decl(objectSpreadUnion.ts, 5, 3)) +>result.a : Symbol(a, Decl(objectSpreadUnion.ts, 1, 14), Decl(objectSpreadUnion.ts, 2, 14)) +>result : Symbol(result, Decl(objectSpreadUnion.ts, 4, 3)) +>a : Symbol(a, Decl(objectSpreadUnion.ts, 1, 14), Decl(objectSpreadUnion.ts, 2, 14)) + +let assignable: { ...(A1 | A2) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadUnion.ts, 6, 3)) +>A1 : Symbol(A1, Decl(objectSpreadUnion.ts, 0, 0)) +>A2 : Symbol(A2, Decl(objectSpreadUnion.ts, 1, 26)) +>result : Symbol(result, Decl(objectSpreadUnion.ts, 4, 3)) + +function tripleUnion(t: T, u: U, v: V): void { +>tripleUnion : Symbol(tripleUnion, Decl(objectSpreadUnion.ts, 6, 42)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 8, 21)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 8, 23)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 8, 26)) +>t : Symbol(t, Decl(objectSpreadUnion.ts, 8, 30)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 8, 21)) +>u : Symbol(u, Decl(objectSpreadUnion.ts, 8, 35)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 8, 23)) +>v : Symbol(v, Decl(objectSpreadUnion.ts, 8, 41)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 8, 26)) + + let tuv: T | U | V; +>tuv : Symbol(tuv, Decl(objectSpreadUnion.ts, 9, 7)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 8, 21)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 8, 23)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 8, 26)) + + let result = { id: 'foo', ...tuv }; +>result : Symbol(result, Decl(objectSpreadUnion.ts, 10, 7)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 10, 18)) + + let expected: { id: string, ...T } | { id: string, ...U } | { id: string, ...V } = result; +>expected : Symbol(expected, Decl(objectSpreadUnion.ts, 11, 7)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 11, 19)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 8, 21)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 11, 42)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 8, 23)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 11, 65)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 8, 26)) +>result : Symbol(result, Decl(objectSpreadUnion.ts, 10, 7)) + + let assignable: { id: string, ...(T | U | V) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadUnion.ts, 12, 7)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 12, 21)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 8, 21)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 8, 23)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 8, 26)) +>result : Symbol(result, Decl(objectSpreadUnion.ts, 10, 7)) +} +function iteratedDoubleUnion(t: T, u: U, v: V): void { +>iteratedDoubleUnion : Symbol(iteratedDoubleUnion, Decl(objectSpreadUnion.ts, 13, 1)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 14, 29)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 14, 34)) +>t : Symbol(t, Decl(objectSpreadUnion.ts, 14, 38)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 14, 29)) +>u : Symbol(u, Decl(objectSpreadUnion.ts, 14, 43)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>v : Symbol(v, Decl(objectSpreadUnion.ts, 14, 49)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 14, 34)) + + let tu: T | U; +>tu : Symbol(tu, Decl(objectSpreadUnion.ts, 15, 7)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 14, 29)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) + + let uv: U | V; +>uv : Symbol(uv, Decl(objectSpreadUnion.ts, 16, 7)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 14, 34)) + + let result = { id: 'bar', ...tu, ...uv }; +>result : Symbol(result, Decl(objectSpreadUnion.ts, 17, 7)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 17, 18)) + + let expected: { id: string, ...T, ...U } | { id: string, ...T, ...V } | { id: string, ...U } | { id: string, ...U, ...V }; +>expected : Symbol(expected, Decl(objectSpreadUnion.ts, 18, 7)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 18, 19)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 14, 29)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 18, 48)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 14, 29)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 14, 34)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 18, 77)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 18, 100)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 14, 34)) + + let assignable: { id: string, ...(T | U), ...(U | V) } = result; +>assignable : Symbol(assignable, Decl(objectSpreadUnion.ts, 19, 7)) +>id : Symbol(id, Decl(objectSpreadUnion.ts, 19, 21)) +>T : Symbol(T, Decl(objectSpreadUnion.ts, 14, 29)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>U : Symbol(U, Decl(objectSpreadUnion.ts, 14, 31)) +>V : Symbol(V, Decl(objectSpreadUnion.ts, 14, 34)) +>result : Symbol(result, Decl(objectSpreadUnion.ts, 17, 7)) +} + + + diff --git a/tests/baselines/reference/objectSpreadUnion.types b/tests/baselines/reference/objectSpreadUnion.types new file mode 100644 index 00000000000..7cbffcf0a58 --- /dev/null +++ b/tests/baselines/reference/objectSpreadUnion.types @@ -0,0 +1,131 @@ +=== tests/cases/conformance/types/spread/objectSpreadUnion.ts === +// concrete types work +interface A1 { a: number } +>A1 : A1 +>a : number + +interface A2 { a: string } +>A2 : A2 +>a : string + +let a12: A1 | A2; +>a12 : A1 | A2 +>A1 : A1 +>A2 : A2 + +let result = { ...a12 }; +>result : { a: number; } | { a: string; } +>{ ...a12 } : { a: number; } | { a: string; } +>a12 : any + +let sn: number | string = result.a; +>sn : string | number +>result.a : string | number +>result : { a: number; } | { a: string; } +>a : string | number + +let assignable: { ...(A1 | A2) } = result; +>assignable : { a: number; } | { a: string; } +>A1 : A1 +>A2 : A2 +>result : { a: number; } | { a: string; } + +function tripleUnion(t: T, u: U, v: V): void { +>tripleUnion : (t: T, u: U, v: V) => void +>T : T +>U : U +>V : V +>t : T +>T : T +>u : U +>U : U +>v : V +>V : V + + let tuv: T | U | V; +>tuv : T | U | V +>T : T +>U : U +>V : V + + let result = { id: 'foo', ...tuv }; +>result : { id: string; ...T } | { id: string; ...U } | { id: string; ...V } +>{ id: 'foo', ...tuv } : { id: string; ...T } | { id: string; ...U } | { id: string; ...V } +>id : string +>'foo' : "foo" +>tuv : any + + let expected: { id: string, ...T } | { id: string, ...U } | { id: string, ...V } = result; +>expected : { id: string; ...T } | { id: string; ...U } | { id: string; ...V } +>id : string +>T : T +>id : string +>U : U +>id : string +>V : V +>result : { id: string; ...T } | { id: string; ...U } | { id: string; ...V } + + let assignable: { id: string, ...(T | U | V) } = result; +>assignable : { id: string; ...T } | { id: string; ...U } | { id: string; ...V } +>id : string +>T : T +>U : U +>V : V +>result : { id: string; ...T } | { id: string; ...U } | { id: string; ...V } +} +function iteratedDoubleUnion(t: T, u: U, v: V): void { +>iteratedDoubleUnion : (t: T, u: U, v: V) => void +>T : T +>U : U +>V : V +>t : T +>T : T +>u : U +>U : U +>v : V +>V : V + + let tu: T | U; +>tu : T | U +>T : T +>U : U + + let uv: U | V; +>uv : U | V +>U : U +>V : V + + let result = { id: 'bar', ...tu, ...uv }; +>result : { id: string; ...T; ...U } | { id: string; ...U } | { id: string; ...T; ...V } | { id: string; ...U; ...V } +>{ id: 'bar', ...tu, ...uv } : { id: string; ...T; ...U } | { id: string; ...U } | { id: string; ...T; ...V } | { id: string; ...U; ...V } +>id : string +>'bar' : "bar" +>tu : any +>uv : any + + let expected: { id: string, ...T, ...U } | { id: string, ...T, ...V } | { id: string, ...U } | { id: string, ...U, ...V }; +>expected : { id: string; ...T; ...U } | { id: string; ...T; ...V } | { id: string; ...U } | { id: string; ...U; ...V } +>id : string +>T : T +>U : U +>id : string +>T : T +>V : V +>id : string +>U : U +>id : string +>U : U +>V : V + + let assignable: { id: string, ...(T | U), ...(U | V) } = result; +>assignable : { id: string; ...T; ...U } | { id: string; ...U } | { id: string; ...T; ...V } | { id: string; ...U; ...V } +>id : string +>T : T +>U : U +>U : U +>V : V +>result : { id: string; ...T; ...U } | { id: string; ...U } | { id: string; ...T; ...V } | { id: string; ...U; ...V } +} + + + diff --git a/tests/cases/conformance/types/spread/objectSpread.ts b/tests/cases/conformance/types/spread/objectSpread.ts index 9828e86f0a6..e94775649e7 100644 --- a/tests/cases/conformance/types/spread/objectSpread.ts +++ b/tests/cases/conformance/types/spread/objectSpread.ts @@ -35,11 +35,13 @@ let getter: { a: number, c: number } = { ...op, c: 7 } getter.a = 12; -// null and undefined are just skipped -let spreadNull: { a: number } = - { a: 7, ...null } -let spreadUndefined: { a: number } = - { a: 7, ...undefined } +// null, undefined, functions and primitives result in { } +let spreadNull = { ...null }; +let spreadUndefind = { ...undefined }; +let spreadNum = { ...12 }; +let spreadStr = { ...'foo' }; +let spreadBool = { ...false }; +let spreadFunc = { ...(function () { }) }; // methods are not enumerable class C { p = 1; m() { } } diff --git a/tests/cases/conformance/types/spread/objectSpreadIntersection.ts b/tests/cases/conformance/types/spread/objectSpreadIntersection.ts new file mode 100644 index 00000000000..6471e622b68 --- /dev/null +++ b/tests/cases/conformance/types/spread/objectSpreadIntersection.ts @@ -0,0 +1,36 @@ +function iteratedUnionIntersection(t: T, u: U, v: V): void { + let tu: T | U; + let uv: U & V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: ({ id: string, ...T, ...U } & { id: string, ...T, ...V }) | ({ id: string, ...U } & { id: string, ...U, ...V }); + let assignable: { id: string, ...(T | U), ...(U & V) } = result; +} +// concrete types work +interface A1 { a: number } +interface A2 { a: string } +let a12: A1 & A2; +let result = { ...a12 }; +let sn: number & string = result.a; +let assignable: { ...(A1 & A2) } = result; + +function tripleIntersection(t: T, u: U, v: V): void { + let tuv: T & U & V; + let result = { id: 'foo', ...tuv }; + let expected: { id: string, ...T } & { id: string, ...U } & { id: string, ...V } = result; + let assignable: { id: string, ...(T & U & V) } = result; +} +function iteratedDoubleIntersection(t: T, u: U, v: V): void { + let tu: T & U; + let uv: U & V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: { id: string, ...T, ...U } & { id: string, ...T, ...V } & { id: string, ...U } & { id: string, ...U, ...V }; + let assignable: { id: string, ...(T & U), ...(U & V) } = result; +} +function iteratedIntersectionUnion(t: T, u: U, v: V): void { + let tu: T & U; + let uv: U | V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: ({ id: string, ...T, ...U } & { id: string, ...U }) | ({ id: string, ...T, ...V } & { id: string, ...U, ...V }); + let assignable: { id: string, ...(T & U), ...(U | V) } = result; +} + diff --git a/tests/cases/conformance/types/spread/objectSpreadNegative.ts b/tests/cases/conformance/types/spread/objectSpreadNegative.ts index d492db4c638..04a88d2a427 100644 --- a/tests/cases/conformance/types/spread/objectSpreadNegative.ts +++ b/tests/cases/conformance/types/spread/objectSpreadNegative.ts @@ -8,8 +8,8 @@ class PrivateOptionalX { class PublicX { public x: number; } -let o3: { ...PublicX, ...PrivateOptionalX }; -let sn: number = o3.x; // error, x is private +let o2: { ...PublicX, ...PrivateOptionalX }; +let sn: number = o2.x; // error, x is private let optionalString: { sn?: string }; let optionalNumber: { sn?: number }; let allOptional: { sn: string | number } = { ...optionalString, ...optionalNumber }; @@ -22,14 +22,29 @@ let spread: { ...Bool, ...Str } = { s: 'foo' }; // error, missing 'b' let b: Bool; spread = b; // error, missing 's' -// expressions are not allowed -let o1 = { ...1 + 1 }; -let o2 = { ...(1 + 1) }; - // literal repeats are not allowed, but spread repeats are fine let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } let duplicatedSpread = { ...o, ...o } +// null and undefined are just skipped +let spreadNull = { ...null } +spreadNull.null; +let spreadUndefined = { ...undefined } +spreadUndefined.undefined; + +// primitives and functions are skipped +let spreadNum = { ...12 }; +spreadNum.toFixed(); // error, no methods from number +let spreadSum = { ...1 + 1 }; +spreadSum.toFixed(); // error, no methods from number +let spreadStr = { ...'foo' }; +spreadStr.length; // error, no 'length' +spreadStr.charAt(1); // error, no methods either +let spreadBool = { ...true }; +spreadBool.valueOf(); // error, what were you thinking? +let spreadFunc = { ...function () { } } +spreadFunc(); // error, no call signature + // write-only properties get skipped let setterOnly = { ...{ set b (bad: number) { } } }; setterOnly.b = 12; // error, 'b' does not exist @@ -44,9 +59,6 @@ let callableConstructableSpread: { ...PublicX, (n: number): number, new (p: numb callableConstructableSpread(12); // error, no call signature new callableConstructableSpread(12); // error, no construct signature -let publicx: PublicX; -let callableSpread = { ...publicx, ...(n => n + 1) }; // error, can't spread functions - // { ...U } is not assignable to U function override(initial: U, override: U): U { return { ...initial, ...override }; diff --git a/tests/cases/conformance/types/spread/objectSpreadUnion.ts b/tests/cases/conformance/types/spread/objectSpreadUnion.ts new file mode 100644 index 00000000000..03a4251ca81 --- /dev/null +++ b/tests/cases/conformance/types/spread/objectSpreadUnion.ts @@ -0,0 +1,23 @@ +// concrete types work +interface A1 { a: number } +interface A2 { a: string } +let a12: A1 | A2; +let result = { ...a12 }; +let sn: number | string = result.a; +let assignable: { ...(A1 | A2) } = result; + +function tripleUnion(t: T, u: U, v: V): void { + let tuv: T | U | V; + let result = { id: 'foo', ...tuv }; + let expected: { id: string, ...T } | { id: string, ...U } | { id: string, ...V } = result; + let assignable: { id: string, ...(T | U | V) } = result; +} +function iteratedDoubleUnion(t: T, u: U, v: V): void { + let tu: T | U; + let uv: U | V; + let result = { id: 'bar', ...tu, ...uv }; + let expected: { id: string, ...T, ...U } | { id: string, ...T, ...V } | { id: string, ...U } | { id: string, ...U, ...V }; + let assignable: { id: string, ...(T | U), ...(U | V) } = result; +} + +