From c8db211d90424abd949805264f724dc4adbbb53e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 26 Sep 2016 09:33:27 -0700 Subject: [PATCH] Update baselines --- ...ectBindingPatternAndAssignment3.errors.txt | 26 +- ...uringObjectBindingPatternAndAssignment3.js | 9 +- .../duplicateObjectLiteralProperty.errors.txt | 8 +- .../reference/interfaceSpread.errors.txt | 21 + tests/baselines/reference/interfaceSpread.js | 15 + .../lastPropertyInLiteralWins.errors.txt | 8 +- .../reference/memberOverride.errors.txt | 5 +- .../reference/objectLiteralErrors.errors.txt | 5 +- ...tiesErrorFromNotUsingIdentifier.errors.txt | 8 +- tests/baselines/reference/objectSpread.js | 181 ++++++ .../baselines/reference/objectSpread.symbols | 369 ++++++++++++ tests/baselines/reference/objectSpread.types | 530 ++++++++++++++++++ .../reference/objectSpreadGeneric.errors.txt | 80 +++ .../reference/objectSpreadGeneric.js | 79 +++ .../reference/objectSpreadNegative.errors.txt | 93 +++ .../reference/objectSpreadNegative.js | 108 ++++ .../objectSpreadNegativeParse.errors.txt | 35 ++ .../reference/objectSpreadNegativeParse.js | 21 + 18 files changed, 1569 insertions(+), 32 deletions(-) create mode 100644 tests/baselines/reference/interfaceSpread.errors.txt create mode 100644 tests/baselines/reference/interfaceSpread.js create mode 100644 tests/baselines/reference/objectSpread.js create mode 100644 tests/baselines/reference/objectSpread.symbols create mode 100644 tests/baselines/reference/objectSpread.types create mode 100644 tests/baselines/reference/objectSpreadGeneric.errors.txt create mode 100644 tests/baselines/reference/objectSpreadGeneric.js create mode 100644 tests/baselines/reference/objectSpreadNegative.errors.txt create mode 100644 tests/baselines/reference/objectSpreadNegative.js create mode 100644 tests/baselines/reference/objectSpreadNegativeParse.errors.txt create mode 100644 tests/baselines/reference/objectSpreadNegativeParse.js diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt index bb4b79987e3..33344b9b5eb 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt @@ -5,16 +5,12 @@ tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAs tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(4,6): error TS2459: Type 'string | number | {}' has no property 'i1' and no string index signature. tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(5,12): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(5,21): error TS2353: Object literal may only specify known properties, and 'f212' does not exist in type '{ f21: any; }'. -tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(6,7): error TS1180: Property destructuring pattern expected. -tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(7,5): error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ d1: any; }'. -tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(7,11): error TS2353: Object literal may only specify known properties, and 'b' does not exist in type '{ d1: any; }'. -tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(7,24): error TS2353: Object literal may only specify known properties, and 'e' does not exist in type '{ d1: any; }'. -tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(9,7): error TS1005: ':' expected. -tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(9,15): error TS1005: ':' expected. -tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(10,12): error TS1005: ':' expected. +tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(6,7): error TS1005: ':' expected. +tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(6,15): error TS1005: ':' expected. +tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts(7,12): error TS1005: ':' expected. -==== tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts (13 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment3.ts (9 errors) ==== // Error var {h?} = { h?: 1 }; ~ @@ -33,17 +29,6 @@ tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAs !!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. ~~~~ !!! error TS2353: Object literal may only specify known properties, and 'f212' does not exist in type '{ f21: any; }'. - var { ...d1 } = { - ~~~ -!!! error TS1180: Property destructuring pattern expected. - a: 1, b: 1, d1: 9, e: 10 - ~ -!!! error TS2353: Object literal may only specify known properties, and 'a' does not exist in type '{ d1: any; }'. - ~ -!!! error TS2353: Object literal may only specify known properties, and 'b' does not exist in type '{ d1: any; }'. - ~ -!!! error TS2353: Object literal may only specify known properties, and 'e' does not exist in type '{ d1: any; }'. - } var {1} = { 1 }; ~ !!! error TS1005: ':' expected. @@ -51,4 +36,5 @@ tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAs !!! error TS1005: ':' expected. var {"prop"} = { "prop": 1 }; ~ -!!! error TS1005: ':' expected. \ No newline at end of file +!!! error TS1005: ':' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.js b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.js index 77288e6a542..0872a71c73b 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.js +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.js @@ -4,11 +4,9 @@ var {h?} = { h?: 1 }; var {i}: string | number = { i: 2 }; var {i1}: string | number| {} = { i1: 2 }; var { f2: {f21} = { f212: "string" } }: any = undefined; -var { ...d1 } = { - a: 1, b: 1, d1: 9, e: 10 -} var {1} = { 1 }; -var {"prop"} = { "prop": 1 }; +var {"prop"} = { "prop": 1 }; + //// [destructuringObjectBindingPatternAndAssignment3.js] // Error @@ -16,8 +14,5 @@ var h = { h: 1 }.h; var i = { i: 2 }.i; var i1 = { i1: 2 }.i1; var _a = undefined.f2, f21 = (_a === void 0 ? { f212: "string" } : _a).f21; -var d1 = { - a: 1, b: 1, d1: 9, e: 10 -}.d1; var = { 1: }[1]; var = { "prop": 1 }["prop"]; diff --git a/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt b/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt index abc56a6f8fc..926a7071222 100644 --- a/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt +++ b/tests/baselines/reference/duplicateObjectLiteralProperty.errors.txt @@ -1,6 +1,8 @@ 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'. @@ -8,7 +10,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 (8 errors) ==== +==== tests/cases/compiler/duplicateObjectLiteralProperty.ts (10 errors) ==== var x = { a: 1, b: true, // OK @@ -18,9 +20,13 @@ 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 new file mode 100644 index 00000000000..27aab11491c --- /dev/null +++ b/tests/baselines/reference/interfaceSpread.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/es6/destructuring/interfaceSpread.ts(2,5): error TS2699: Interface declaration cannot contain a spread property. +tests/cases/conformance/es6/destructuring/interfaceSpread.ts(7,10): error TS2339: Property 'jam' does not exist on type 'Congealed<{ jam: number; }, { peanutButter: number; }>'. +tests/cases/conformance/es6/destructuring/interfaceSpread.ts(8,10): error TS2339: Property 'peanutButter' does not exist on type 'Congealed<{ jam: number; }, { peanutButter: number; }>'. + + +==== tests/cases/conformance/es6/destructuring/interfaceSpread.ts (3 errors) ==== + interface Congealed { + ...T + ~~~~ +!!! error TS2699: Interface declaration cannot contain a spread property. + ...U + } + + let sandwich: Congealed<{jam: number }, { peanutButter: number }>; + sandwich.jam; + ~~~ +!!! error TS2339: Property 'jam' does not exist on type 'Congealed<{ jam: number; }, { peanutButter: number; }>'. + sandwich.peanutButter; + ~~~~~~~~~~~~ +!!! error TS2339: Property 'peanutButter' does not exist on type 'Congealed<{ jam: number; }, { peanutButter: number; }>'. + \ No newline at end of file diff --git a/tests/baselines/reference/interfaceSpread.js b/tests/baselines/reference/interfaceSpread.js new file mode 100644 index 00000000000..89f25314366 --- /dev/null +++ b/tests/baselines/reference/interfaceSpread.js @@ -0,0 +1,15 @@ +//// [interfaceSpread.ts] +interface Congealed { + ...T + ...U +} + +let sandwich: Congealed<{jam: number }, { peanutButter: number }>; +sandwich.jam; +sandwich.peanutButter; + + +//// [interfaceSpread.js] +var sandwich; +sandwich.jam; +sandwich.peanutButter; diff --git a/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt b/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt index 2b4a694975b..c8844f2c572 100644 --- a/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt +++ b/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt @@ -4,10 +4,12 @@ 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 (3 errors) ==== +==== tests/cases/compiler/lastPropertyInLiteralWins.ts (5 errors) ==== interface Thing { thunk: (str: string) => void; } @@ -22,6 +24,8 @@ tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2300: Duplicate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~ !!! 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'. @@ -35,5 +39,7 @@ tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2300: Duplicate 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 15c4b2ad37b..355db001505 100644 --- a/tests/baselines/reference/memberOverride.errors.txt +++ b/tests/baselines/reference/memberOverride.errors.txt @@ -1,7 +1,8 @@ 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 (1 errors) ==== +==== tests/cases/compiler/memberOverride.ts (2 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 = { @@ -9,6 +10,8 @@ tests/cases/compiler/memberOverride.ts(5,5): error TS2300: Duplicate identifier 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 234ac24a8fd..f70f255df05 100644 --- a/tests/baselines/reference/objectLiteralErrors.errors.txt +++ b/tests/baselines/reference/objectLiteralErrors.errors.txt @@ -1,6 +1,7 @@ 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''. @@ -78,7 +79,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 (78 errors) ==== +==== tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts (79 errors) ==== // Multiple properties with the same name var e1 = { a: 0, a: 0 }; @@ -90,6 +91,8 @@ 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 5fa8a12e875..cbe19cab2d2 100644 --- a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.errors.txt @@ -8,12 +8,14 @@ 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 (13 errors) ==== +==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.ts (15 errors) ==== // errors var y = { "stringLiteral", @@ -50,9 +52,13 @@ 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 new file mode 100644 index 00000000000..a59577fe9de --- /dev/null +++ b/tests/baselines/reference/objectSpread.js @@ -0,0 +1,181 @@ +//// [objectSpread.ts] +let o = { a: 1, b: 'no' } +let o2 = { b: 'yes', c: true } +let swap = { a: 'yes', b: -1 }; + +let addAfter: { a: number, b: string, c: boolean } = + { ...o, c: false } +let addBefore: { a: number, b: string, c: boolean } = + { c: false, ...o } +// Note: ignore still changes the order that properties are printed +let ignore: { a: number, b: string } = + { b: 'ignored', ...o } +let override: { a: number, b: string } = + { ...o, b: 'override' } +let nested: { a: number, b: boolean, c: string } = + { ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } +let combined: { a: number, b: string, c: boolean } = + { ...o, ...o2 } +let combinedBefore: { a: number, b: string, c: boolean } = + { b: 'ok', ...o, ...o2 } +let combinedMid: { a: number, b: string, c: boolean } = + { ...o, b: 'ok', ...o2 } +let combinedAfter: { a: number, b: string, c: boolean } = + { ...o, ...o2, b: 'ok' } +let combinedNested: { a: number, b: boolean, c: string, d: string } = + { ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } +let combinedNestedChangeType: { a: number, b: boolean, c: number } = + { ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } +let propertyNested: { a: { a: number, b: string } } = + { a: { ... o } } +// accessors don't copy the descriptor +// (which means that readonly getters become read/write properties) +let op = { get a () { return 6 } }; +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 } + +// methods are not enumerable +class C { p = 1; m() { } } +let c: C = new C() +let spreadC: { p: number } = { ...c } + +// own methods are enumerable +let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } }; +cplus.plus(); + +// new field's type conflicting with existing field is OK +let changeTypeAfter: { a: string, b: string } = + { ...o, a: 'wrong type?' } +let changeTypeBefore: { a: number, b: string } = + { a: 'wrong type?', ...o }; +let changeTypeBoth: { a: string, b: number } = + { ...o, ...swap }; + +// optional +let definiteBoolean: { sn: boolean }; +let definiteString: { sn: string }; +let optionalString: { sn?: string }; +let optionalNumber: { sn?: number }; +let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; +let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; +let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; + +// computed property +let computedFirst: { a: number, b: string, "before everything": number } = + { ['before everything']: 12, ...o, b: 'yes' } +let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = + { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } +let computedAfter: { a: number, b: string, "at the end": number } = + { ...o, b: 'yeah', ['at the end']: 14 } +// shortcut syntax +let a = 12; +let shortCutted: { a: number, b: string } = { ...o, a } + +// generics +function f(t: T, u: U): { id: string, ...T, ...U } { + return { id: 'id', ...t, ...u }; +} +let exclusive: { id: string, a: number, b: string, c: string, d: boolean } = + f({ a: 1, b: 'yes' }, { c: 'no', d: false }) +let overlap: { id: string, a: number, b: string } = + f({ a: 1 }, { a: 2, b: 'extra' }) +let overlapConflict: { id:string, a: string } = + f({ a: 1 }, { a: 'mismatch' }) +let overwriteId: { id: boolean, a: number, c: number, d: string } = + f({ a: 1, id: true }, { c: 1, d: 'no' }) + +class D { m() { }; q = 2; } +let classesAreWrong: { id: string, ...C, ...D } = + f(new C(), new D()) + + +//// [objectSpread.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 o = { a: 1, b: 'no' }; +var o2 = { b: 'yes', c: true }; +var swap = { a: 'yes', b: -1 }; +var addAfter = __assign({}, o, { c: false }); +var addBefore = __assign({ c: false }, o); +// Note: ignore still changes the order that properties are printed +var ignore = __assign({ b: 'ignored' }, o); +var override = __assign({}, o, { b: 'override' }); +var nested = __assign({}, __assign({ a: 3 }, { b: false, c: 'overriden' }), { c: 'whatever' }); +var combined = __assign({}, o, o2); +var combinedBefore = __assign({ b: 'ok' }, o, o2); +var combinedMid = __assign({}, o, { b: 'ok' }, o2); +var combinedAfter = __assign({}, o, o2, { b: 'ok' }); +var combinedNested = __assign({}, __assign({ a: 4 }, { b: false, c: 'overriden' }), { d: 'actually new' }, { a: 5, d: 'maybe new' }); +var combinedNestedChangeType = __assign({}, __assign({ a: 1 }, { b: false, c: 'overriden' }), { c: -1 }); +var propertyNested = __assign({ a: __assign({}, o) }); +// accessors don't copy the descriptor +// (which means that readonly getters become read/write properties) +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); +// methods are not enumerable +var C = (function () { + function C() { + this.p = 1; + } + C.prototype.m = function () { }; + return C; +}()); +var c = new C(); +var spreadC = __assign({}, c); +// own methods are enumerable +var cplus = __assign({}, c, { plus: function () { return this.p + 1; } }); +cplus.plus(); +// new field's type conflicting with existing field is OK +var changeTypeAfter = __assign({}, o, { a: 'wrong type?' }); +var changeTypeBefore = __assign({ a: 'wrong type?' }, o); +var changeTypeBoth = __assign({}, o, swap); +// optional +var definiteBoolean; +var definiteString; +var optionalString; +var optionalNumber; +var optionalUnionStops = __assign({}, definiteBoolean, definiteString, optionalNumber); +var optionalUnionDuplicates = __assign({}, definiteBoolean, definiteString, optionalString, optionalNumber); +var allOptional = __assign({}, optionalString, optionalNumber); +// computed property +var computedFirst = __assign((_a = {}, _a['before everything'] = 12, _a), o, { b: 'yes' }); +var computedMiddle = __assign({}, o, (_b = {}, _b['in the middle'] = 13, _b.b = 'maybe?', _b), o2); +var computedAfter = __assign({}, o, (_c = { b: 'yeah' }, _c['at the end'] = 14, _c)); +// shortcut syntax +var a = 12; +var shortCutted = __assign({}, o, { a: a }); +// generics +function f(t, u) { + return __assign({ id: 'id' }, t, u); +} +var exclusive = f({ a: 1, b: 'yes' }, { c: 'no', d: false }); +var overlap = f({ a: 1 }, { a: 2, b: 'extra' }); +var overlapConflict = f({ a: 1 }, { a: 'mismatch' }); +var overwriteId = f({ a: 1, id: true }, { c: 1, d: 'no' }); +var D = (function () { + function D() { + this.q = 2; + } + D.prototype.m = function () { }; + ; + return D; +}()); +var classesAreWrong = f(new C(), new D()); +var _a, _b, _c; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols new file mode 100644 index 00000000000..001c42804d2 --- /dev/null +++ b/tests/baselines/reference/objectSpread.symbols @@ -0,0 +1,369 @@ +=== tests/cases/conformance/types/spread/objectSpread.ts === +let o = { a: 1, b: 'no' } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 0, 9)) +>b : Symbol(b, Decl(objectSpread.ts, 0, 15)) + +let o2 = { b: 'yes', c: true } +>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3)) +>b : Symbol(b, Decl(objectSpread.ts, 1, 10)) +>c : Symbol(c, Decl(objectSpread.ts, 1, 20)) + +let swap = { a: 'yes', b: -1 }; +>swap : Symbol(swap, Decl(objectSpread.ts, 2, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 2, 12)) +>b : Symbol(b, Decl(objectSpread.ts, 2, 22)) + +let addAfter: { a: number, b: string, c: boolean } = +>addAfter : Symbol(addAfter, Decl(objectSpread.ts, 4, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 4, 15)) +>b : Symbol(b, Decl(objectSpread.ts, 4, 26)) +>c : Symbol(c, Decl(objectSpread.ts, 4, 37)) + + { ...o, c: false } +>c : Symbol(c, Decl(objectSpread.ts, 5, 11)) + +let addBefore: { a: number, b: string, c: boolean } = +>addBefore : Symbol(addBefore, Decl(objectSpread.ts, 6, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 6, 16)) +>b : Symbol(b, Decl(objectSpread.ts, 6, 27)) +>c : Symbol(c, Decl(objectSpread.ts, 6, 38)) + + { c: false, ...o } +>c : Symbol(c, Decl(objectSpread.ts, 7, 5)) + +// Note: ignore still changes the order that properties are printed +let ignore: { a: number, b: string } = +>ignore : Symbol(ignore, Decl(objectSpread.ts, 9, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 9, 13)) +>b : Symbol(b, Decl(objectSpread.ts, 9, 24)) + + { b: 'ignored', ...o } +>b : Symbol(b, Decl(objectSpread.ts, 10, 5)) + +let override: { a: number, b: string } = +>override : Symbol(override, Decl(objectSpread.ts, 11, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 11, 15)) +>b : Symbol(b, Decl(objectSpread.ts, 11, 26)) + + { ...o, b: 'override' } +>b : Symbol(b, Decl(objectSpread.ts, 12, 11)) + +let nested: { a: number, b: boolean, c: string } = +>nested : Symbol(nested, Decl(objectSpread.ts, 13, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 13, 13)) +>b : Symbol(b, Decl(objectSpread.ts, 13, 24)) +>c : Symbol(c, Decl(objectSpread.ts, 13, 36)) + + { ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } +>a : Symbol(a, Decl(objectSpread.ts, 14, 10)) +>b : Symbol(b, Decl(objectSpread.ts, 14, 21)) +>c : Symbol(c, Decl(objectSpread.ts, 14, 31)) +>c : Symbol(c, Decl(objectSpread.ts, 14, 51)) + +let combined: { a: number, b: string, c: boolean } = +>combined : Symbol(combined, Decl(objectSpread.ts, 15, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 15, 15)) +>b : Symbol(b, Decl(objectSpread.ts, 15, 26)) +>c : Symbol(c, Decl(objectSpread.ts, 15, 37)) + + { ...o, ...o2 } +let combinedBefore: { a: number, b: string, c: boolean } = +>combinedBefore : Symbol(combinedBefore, Decl(objectSpread.ts, 17, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 17, 21)) +>b : Symbol(b, Decl(objectSpread.ts, 17, 32)) +>c : Symbol(c, Decl(objectSpread.ts, 17, 43)) + + { b: 'ok', ...o, ...o2 } +>b : Symbol(b, Decl(objectSpread.ts, 18, 5)) + +let combinedMid: { a: number, b: string, c: boolean } = +>combinedMid : Symbol(combinedMid, Decl(objectSpread.ts, 19, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 19, 18)) +>b : Symbol(b, Decl(objectSpread.ts, 19, 29)) +>c : Symbol(c, Decl(objectSpread.ts, 19, 40)) + + { ...o, b: 'ok', ...o2 } +>b : Symbol(b, Decl(objectSpread.ts, 20, 11)) + +let combinedAfter: { a: number, b: string, c: boolean } = +>combinedAfter : Symbol(combinedAfter, Decl(objectSpread.ts, 21, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 21, 20)) +>b : Symbol(b, Decl(objectSpread.ts, 21, 31)) +>c : Symbol(c, Decl(objectSpread.ts, 21, 42)) + + { ...o, ...o2, b: 'ok' } +>b : Symbol(b, Decl(objectSpread.ts, 22, 18)) + +let combinedNested: { a: number, b: boolean, c: string, d: string } = +>combinedNested : Symbol(combinedNested, Decl(objectSpread.ts, 23, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 23, 21)) +>b : Symbol(b, Decl(objectSpread.ts, 23, 32)) +>c : Symbol(c, Decl(objectSpread.ts, 23, 44)) +>d : Symbol(d, Decl(objectSpread.ts, 23, 55)) + + { ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } +>a : Symbol(a, Decl(objectSpread.ts, 24, 10)) +>b : Symbol(b, Decl(objectSpread.ts, 24, 21)) +>c : Symbol(c, Decl(objectSpread.ts, 24, 31)) +>d : Symbol(d, Decl(objectSpread.ts, 24, 51)) +>a : Symbol(a, Decl(objectSpread.ts, 24, 75)) +>d : Symbol(d, Decl(objectSpread.ts, 24, 81)) + +let combinedNestedChangeType: { a: number, b: boolean, c: number } = +>combinedNestedChangeType : Symbol(combinedNestedChangeType, Decl(objectSpread.ts, 25, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 25, 31)) +>b : Symbol(b, Decl(objectSpread.ts, 25, 42)) +>c : Symbol(c, Decl(objectSpread.ts, 25, 54)) + + { ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } +>a : Symbol(a, Decl(objectSpread.ts, 26, 10)) +>b : Symbol(b, Decl(objectSpread.ts, 26, 21)) +>c : Symbol(c, Decl(objectSpread.ts, 26, 31)) +>c : Symbol(c, Decl(objectSpread.ts, 26, 51)) + +let propertyNested: { a: { a: number, b: string } } = +>propertyNested : Symbol(propertyNested, Decl(objectSpread.ts, 27, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 27, 21)) +>a : Symbol(a, Decl(objectSpread.ts, 27, 26)) +>b : Symbol(b, Decl(objectSpread.ts, 27, 37)) + + { a: { ... o } } +>a : Symbol(a, Decl(objectSpread.ts, 28, 5)) + +// accessors don't copy the descriptor +// (which means that readonly getters become read/write properties) +let op = { get a () { return 6 } }; +>op : Symbol(op, Decl(objectSpread.ts, 31, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 31, 10)) + +let getter: { a: number, c: number } = +>getter : Symbol(getter, Decl(objectSpread.ts, 32, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 32, 13)) +>c : Symbol(c, Decl(objectSpread.ts, 32, 24)) + + { ...op, c: 7 } +>c : Symbol(c, Decl(objectSpread.ts, 33, 12)) + +getter.a = 12; +>getter.a : Symbol(a, Decl(objectSpread.ts, 32, 13)) +>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 } = +>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 spreadUndefined: { a: number } = +>spreadUndefined : Symbol(spreadUndefined, Decl(objectSpread.ts, 39, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 39, 22)) + + { a: 7, ...undefined } +>a : Symbol(a, Decl(objectSpread.ts, 40, 5)) + +// 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)) + +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)) + +let spreadC: { p: number } = { ...c } +>spreadC : Symbol(spreadC, Decl(objectSpread.ts, 45, 3)) +>p : Symbol(p, Decl(objectSpread.ts, 45, 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.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)) + +// 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)) + + { ...o, a: 'wrong type?' } +>a : Symbol(a, Decl(objectSpread.ts, 53, 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)) + + { a: 'wrong type?', ...o }; +>a : Symbol(a, Decl(objectSpread.ts, 55, 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)) + + { ...o, ...swap }; + +// optional +let definiteBoolean: { sn: boolean }; +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 60, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 60, 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)) +>sn : Symbol(sn, Decl(objectSpread.ts, 63, 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)) + +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)) + +let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; +>allOptional : Symbol(allOptional, Decl(objectSpread.ts, 66, 3)) +>sn : Symbol(sn, Decl(objectSpread.ts, 66, 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)) + + { ['before everything']: 12, ...o, b: 'yes' } +>'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 70, 5)) +>b : Symbol(b, Decl(objectSpread.ts, 70, 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)) + + { ...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)) + +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)) + + { ...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)) + +// shortcut syntax +let a = 12; +>a : Symbol(a, Decl(objectSpread.ts, 76, 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)) + +// 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)) + + return { id: 'id', ...t, ...u }; +>id : Symbol(id, Decl(objectSpread.ts, 81, 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)) + + 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)) + +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)) + + 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)) +>a : Symbol(a, Decl(objectSpread.ts, 88, 7)) +>a : Symbol(a, Decl(objectSpread.ts, 88, 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)) + + 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)) + +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)) + +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)) + + 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)) + diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types new file mode 100644 index 00000000000..1a053a22670 --- /dev/null +++ b/tests/baselines/reference/objectSpread.types @@ -0,0 +1,530 @@ +=== tests/cases/conformance/types/spread/objectSpread.ts === +let o = { a: 1, b: 'no' } +>o : { a: number; b: string; } +>{ a: 1, b: 'no' } : { a: number; b: string; } +>a : number +>1 : 1 +>b : string +>'no' : "no" + +let o2 = { b: 'yes', c: true } +>o2 : { b: string; c: boolean; } +>{ b: 'yes', c: true } : { b: string; c: boolean; } +>b : string +>'yes' : "yes" +>c : boolean +>true : true + +let swap = { a: 'yes', b: -1 }; +>swap : { a: string; b: number; } +>{ a: 'yes', b: -1 } : { a: string; b: number; } +>a : string +>'yes' : "yes" +>b : number +>-1 : -1 +>1 : 1 + +let addAfter: { a: number, b: string, c: boolean } = +>addAfter : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + + { ...o, c: false } +>{ ...o, c: false } : { ...{ a: number; b: string; }; c: false; } +>o : any +>c : boolean +>false : false + +let addBefore: { a: number, b: string, c: boolean } = +>addBefore : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + + { c: false, ...o } +>{ c: false, ...o } : { c: false; ...{ a: number; b: string; } } +>c : boolean +>false : false +>o : any + +// Note: ignore still changes the order that properties are printed +let ignore: { a: number, b: string } = +>ignore : { a: number; b: string; } +>a : number +>b : string + + { b: 'ignored', ...o } +>{ b: 'ignored', ...o } : { b: string; ...{ a: number; b: string; } } +>b : string +>'ignored' : "ignored" +>o : any + +let override: { a: number, b: string } = +>override : { a: number; b: string; } +>a : number +>b : string + + { ...o, b: 'override' } +>{ ...o, b: 'override' } : { ...{ a: number; b: string; }; b: string; } +>o : any +>b : string +>'override' : "override" + +let nested: { a: number, b: boolean, c: string } = +>nested : { a: number; b: boolean; c: string; } +>a : number +>b : boolean +>c : string + + { ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } +>{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } : { ...{ a: number; ...{ b: boolean; c: string; } }; c: string; } +>{ a: 3, ...{ b: false, c: 'overriden' } } : { a: number; ...{ b: boolean; c: string; } } +>a : number +>3 : 3 +>{ b: false, c: 'overriden' } : { b: boolean; c: string; } +>b : boolean +>false : false +>c : string +>'overriden' : "overriden" +>c : string +>'whatever' : "whatever" + +let combined: { a: number, b: string, c: boolean } = +>combined : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + + { ...o, ...o2 } +>{ ...o, ...o2 } : { ...{ a: number; b: string; }; ...{ b: string; c: boolean; } } +>o : any +>o2 : any + +let combinedBefore: { a: number, b: string, c: boolean } = +>combinedBefore : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + + { b: 'ok', ...o, ...o2 } +>{ b: 'ok', ...o, ...o2 } : { b: string; ...{ a: number; b: string; }; ...{ b: string; c: boolean; } } +>b : string +>'ok' : "ok" +>o : any +>o2 : any + +let combinedMid: { a: number, b: string, c: boolean } = +>combinedMid : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + + { ...o, b: 'ok', ...o2 } +>{ ...o, b: 'ok', ...o2 } : { ...{ a: number; b: string; }; b: string; ...{ b: string; c: boolean; } } +>o : any +>b : string +>'ok' : "ok" +>o2 : any + +let combinedAfter: { a: number, b: string, c: boolean } = +>combinedAfter : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + + { ...o, ...o2, b: 'ok' } +>{ ...o, ...o2, b: 'ok' } : { ...{ a: number; b: string; }; ...{ b: string; c: boolean; }; b: string; } +>o : any +>o2 : any +>b : string +>'ok' : "ok" + +let combinedNested: { a: number, b: boolean, c: string, d: string } = +>combinedNested : { a: number; b: boolean; c: string; d: string; } +>a : number +>b : boolean +>c : string +>d : string + + { ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } +>{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } : { ...{ a: number; ...{ b: boolean; c: string; } }; d: string; ...{ a: number; d: string; } } +>{ a: 4, ...{ b: false, c: 'overriden' } } : { a: number; ...{ b: boolean; c: string; } } +>a : number +>4 : 4 +>{ b: false, c: 'overriden' } : { b: boolean; c: string; } +>b : boolean +>false : false +>c : string +>'overriden' : "overriden" +>d : string +>'actually new' : "actually new" +>{ a: 5, d: 'maybe new' } : { a: number; d: string; } +>a : number +>5 : 5 +>d : string +>'maybe new' : "maybe new" + +let combinedNestedChangeType: { a: number, b: boolean, c: number } = +>combinedNestedChangeType : { a: number; b: boolean; c: number; } +>a : number +>b : boolean +>c : number + + { ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } +>{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } : { ...{ a: number; ...{ b: boolean; c: string; } }; c: number; } +>{ a: 1, ...{ b: false, c: 'overriden' } } : { a: number; ...{ b: boolean; c: string; } } +>a : number +>1 : 1 +>{ b: false, c: 'overriden' } : { b: boolean; c: string; } +>b : boolean +>false : false +>c : string +>'overriden' : "overriden" +>c : number +>-1 : -1 +>1 : 1 + +let propertyNested: { a: { a: number, b: string } } = +>propertyNested : { a: { a: number; b: string; }; } +>a : { a: number; b: string; } +>a : number +>b : string + + { a: { ... o } } +>{ a: { ... o } } : { a: { ...{ a: number; b: string; } }; } +>a : { ...{ a: number; b: string; } } +>{ ... o } : { ...{ a: number; b: string; } } +>o : any + +// accessors don't copy the descriptor +// (which means that readonly getters become read/write properties) +let op = { get a () { return 6 } }; +>op : { readonly a: number; } +>{ get a () { return 6 } } : { readonly a: number; } +>a : number +>6 : 6 + +let getter: { a: number, c: number } = +>getter : { a: number; c: number; } +>a : number +>c : number + + { ...op, c: 7 } +>{ ...op, c: 7 } : { ...{ readonly a: number; }; c: number; } +>op : any +>c : number +>7 : 7 + +getter.a = 12; +>getter.a = 12 : 12 +>getter.a : number +>getter : { a: number; c: number; } +>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 : null + +let spreadUndefined: { a: number } = +>spreadUndefined : { a: number; } +>a : number + + { a: 7, ...undefined } +>{ a: 7, ...undefined } : { a: number; } +>a : number +>7 : 7 +>undefined : any + +// methods are not enumerable +class C { p = 1; m() { } } +>C : C +>p : number +>1 : 1 +>m : () => void + +let c: C = new C() +>c : C +>C : C +>new C() : C +>C : typeof C + +let spreadC: { p: number } = { ...c } +>spreadC : { p: number; } +>p : number +>{ ...c } : { ...C } +>c : any + +// own methods are enumerable +let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } }; +>cplus : { p: number; plus(): void; } +>p : number +>plus : () => void +>{ ...c, plus() { return this.p + 1; } } : { ...C; plus(): any; } +>c : any +>plus : () => any +>this.p + 1 : any +>this.p : any +>this : any +>p : any +>1 : 1 + +cplus.plus(); +>cplus.plus() : void +>cplus.plus : () => void +>cplus : { p: number; plus(): void; } +>plus : () => void + +// new field's type conflicting with existing field is OK +let changeTypeAfter: { a: string, b: string } = +>changeTypeAfter : { a: string; b: string; } +>a : string +>b : string + + { ...o, a: 'wrong type?' } +>{ ...o, a: 'wrong type?' } : { ...{ a: number; b: string; }; a: string; } +>o : any +>a : string +>'wrong type?' : "wrong type?" + +let changeTypeBefore: { a: number, b: string } = +>changeTypeBefore : { a: number; b: string; } +>a : number +>b : string + + { a: 'wrong type?', ...o }; +>{ a: 'wrong type?', ...o } : { a: string; ...{ a: number; b: string; } } +>a : string +>'wrong type?' : "wrong type?" +>o : any + +let changeTypeBoth: { a: string, b: number } = +>changeTypeBoth : { a: string; b: number; } +>a : string +>b : number + + { ...o, ...swap }; +>{ ...o, ...swap } : { ...{ a: number; b: string; }; ...{ a: string; b: number; } } +>o : any +>swap : any + +// optional +let definiteBoolean: { sn: boolean }; +>definiteBoolean : { sn: boolean; } +>sn : boolean + +let definiteString: { sn: string }; +>definiteString : { sn: string; } +>sn : string + +let optionalString: { sn?: string }; +>optionalString : { sn?: string; } +>sn : string + +let optionalNumber: { sn?: number }; +>optionalNumber : { sn?: number; } +>sn : number + +let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; +>optionalUnionStops : { sn: string | number | boolean; } +>sn : string | number | boolean +>{ ...definiteBoolean, ...definiteString, ...optionalNumber } : { ...{ sn: boolean; }; ...{ sn: string; }; ...{ sn?: number; } } +>definiteBoolean : any +>definiteString : any +>optionalNumber : any + +let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; +>optionalUnionDuplicates : { sn: string | number; } +>sn : string | number +>{ ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber } : { ...{ sn: boolean; }; ...{ sn: string; }; ...{ sn?: string; }; ...{ sn?: number; } } +>definiteBoolean : any +>definiteString : any +>optionalString : any +>optionalNumber : any + +let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; +>allOptional : { sn?: string | number; } +>sn : string | number +>{ ...optionalString, ...optionalNumber } : { ...{ sn?: string; }; ...{ sn?: number; } } +>optionalString : any +>optionalNumber : any + +// computed property +let computedFirst: { a: number, b: string, "before everything": number } = +>computedFirst : { a: number; b: string; "before everything": number; } +>a : number +>b : string + + { ['before everything']: 12, ...o, b: 'yes' } +>{ ['before everything']: 12, ...o, b: 'yes' } : { ['before everything']: number; ...{ a: number; b: string; }; b: string; } +>'before everything' : "before everything" +>12 : 12 +>o : any +>b : string +>'yes' : "yes" + +let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = +>computedMiddle : { a: number; b: string; c: boolean; "in the middle": number; } +>a : number +>b : string +>c : boolean + + { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } +>{ ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } : { ...{ a: number; b: string; }; ['in the middle']: number; b: string; ...{ b: string; c: boolean; } } +>o : any +>'in the middle' : "in the middle" +>13 : 13 +>b : string +>'maybe?' : "maybe?" +>o2 : any + +let computedAfter: { a: number, b: string, "at the end": number } = +>computedAfter : { a: number; b: string; "at the end": number; } +>a : number +>b : string + + { ...o, b: 'yeah', ['at the end']: 14 } +>{ ...o, b: 'yeah', ['at the end']: 14 } : { ...{ a: number; b: string; }; b: string; ['at the end']: number; } +>o : any +>b : string +>'yeah' : "yeah" +>'at the end' : "at the end" +>14 : 14 + +// shortcut syntax +let a = 12; +>a : number +>12 : 12 + +let shortCutted: { a: number, b: string } = { ...o, a } +>shortCutted : { a: number; b: string; } +>a : number +>b : string +>{ ...o, a } : { ...{ a: number; b: string; }; a: number; } +>o : any +>a : number + +// generics +function f(t: T, u: U): { id: string, ...T, ...U } { +>f : (t: T, u: U) => { id: string; ...T; ...U } +>T : T +>U : U +>t : T +>T : T +>u : U +>U : U +>id : string +>T : T +>U : U + + return { id: 'id', ...t, ...u }; +>{ id: 'id', ...t, ...u } : { id: string; ...T; ...U } +>id : string +>'id' : "id" +>t : any +>u : any +} +let exclusive: { id: string, a: number, b: string, c: string, d: boolean } = +>exclusive : { id: string; a: number; b: string; c: string; d: boolean; } +>id : string +>a : number +>b : string +>c : string +>d : boolean + + f({ a: 1, b: 'yes' }, { c: 'no', d: false }) +>f({ a: 1, b: 'yes' }, { c: 'no', d: false }) : { id: string; ...{ a: number; b: string; }; ...{ c: string; d: boolean; } } +>f : (t: T, u: U) => { id: string; ...T; ...U } +>{ a: 1, b: 'yes' } : { a: number; b: string; } +>a : number +>1 : 1 +>b : string +>'yes' : "yes" +>{ c: 'no', d: false } : { c: string; d: false; } +>c : string +>'no' : "no" +>d : boolean +>false : false + +let overlap: { id: string, a: number, b: string } = +>overlap : { id: string; a: number; b: string; } +>id : string +>a : number +>b : string + + f({ a: 1 }, { a: 2, b: 'extra' }) +>f({ a: 1 }, { a: 2, b: 'extra' }) : { id: string; ...{ a: number; }; ...{ a: number; b: string; } } +>f : (t: T, u: U) => { id: string; ...T; ...U } +>{ a: 1 } : { a: number; } +>a : number +>1 : 1 +>{ a: 2, b: 'extra' } : { a: number; b: string; } +>a : number +>2 : 2 +>b : string +>'extra' : "extra" + +let overlapConflict: { id:string, a: string } = +>overlapConflict : { id: string; a: string; } +>id : string +>a : string + + f({ a: 1 }, { a: 'mismatch' }) +>f({ a: 1 }, { a: 'mismatch' }) : { id: string; ...{ a: number; }; ...{ a: string; } } +>f : (t: T, u: U) => { id: string; ...T; ...U } +>{ a: 1 } : { a: number; } +>a : number +>1 : 1 +>{ a: 'mismatch' } : { a: string; } +>a : string +>'mismatch' : "mismatch" + +let overwriteId: { id: boolean, a: number, c: number, d: string } = +>overwriteId : { id: boolean; a: number; c: number; d: string; } +>id : boolean +>a : number +>c : number +>d : string + + f({ a: 1, id: true }, { c: 1, d: 'no' }) +>f({ a: 1, id: true }, { c: 1, d: 'no' }) : { id: string; ...{ a: number; id: boolean; }; ...{ c: number; d: string; } } +>f : (t: T, u: U) => { id: string; ...T; ...U } +>{ a: 1, id: true } : { a: number; id: true; } +>a : number +>1 : 1 +>id : boolean +>true : true +>{ c: 1, d: 'no' } : { c: number; d: string; } +>c : number +>1 : 1 +>d : string +>'no' : "no" + +class D { m() { }; q = 2; } +>D : D +>m : () => void +>q : number +>2 : 2 + +let classesAreWrong: { id: string, ...C, ...D } = +>classesAreWrong : { id: string; ...C; ...D } +>id : string +>C : C +>D : D + + f(new C(), new D()) +>f(new C(), new D()) : { id: string; ...C; ...D } +>f : (t: T, u: U) => { id: string; ...T; ...U } +>new C() : C +>C : typeof C +>new D() : D +>D : typeof D + diff --git a/tests/baselines/reference/objectSpreadGeneric.errors.txt b/tests/baselines/reference/objectSpreadGeneric.errors.txt new file mode 100644 index 00000000000..16dfc835d26 --- /dev/null +++ b/tests/baselines/reference/objectSpreadGeneric.errors.txt @@ -0,0 +1,80 @@ +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(4,11): error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...V; ...U; ...T }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(5,11): error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...U; ...T; ...V }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(6,11): error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...U; ...V }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(7,11): error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...T; ...V }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(8,11): error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...T; ...U }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(13,11): error TS2322: Type '{}' is not assignable to type '{ ...T; ...U }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(26,11): error TS2322: Type '{ first: string; ...T; second: string; ...U; third: string; }' is not assignable to type '{ first: string; second: string; ...T; third: string; }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(34,11): error TS2322: Type '{ firrrrrrst: string; ...T; second: string; ...U; third: string; }' is not assignable to type '{ first: string; ...T; second: string; ...U; third: string; }'. + Property 'first' is missing in type '{ firrrrrrst: string; ...T; second: string; ...U; third: string; }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(36,11): error TS2322: Type '{ first: string; ...T; ssssssssecond: string; ...U; third: string; }' is not assignable to type '{ first: string; ...T; second: string; ...U; third: string; }'. + Property 'second' is missing in type '{ first: string; ...T; ssssssssecond: string; ...U; third: string; }'. +tests/cases/conformance/types/spread/objectSpreadGeneric.ts(38,11): error TS2322: Type '{ first: string; ...T; second: string; ...U; thirrrrrrrd: string; }' is not assignable to type '{ first: string; ...T; second: string; ...U; third: string; }'. + Property 'third' is missing in type '{ first: string; ...T; second: string; ...U; thirrrrrrrd: string; }'. + + +==== tests/cases/conformance/types/spread/objectSpreadGeneric.ts (10 errors) ==== + function f(t: T, u: U, v: V): void { + let o: { ...T, ...U, ...V }; + const same: { ...T, ...U, ...V } = o; // ok + const reversed: { ...V, ...U, ...T } = o; // error, reversed + ~~~~~~~~ +!!! error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...V; ...U; ...T }'. + const reversed2: { ...U, ...T, ...V } = o; // error, U and T are still reversed + ~~~~~~~~~ +!!! error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...U; ...T; ...V }'. + const missingT: { ...U, ...V } = o; // error, missing T + ~~~~~~~~ +!!! error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...U; ...V }'. + const missingU: { ...T, ...V } = o; // error, missing U + ~~~~~~~~ +!!! error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...T; ...V }'. + const missingV: { ...T, ...U } = o; // error, missing V + ~~~~~~~~ +!!! error TS2322: Type '{ ...T; ...U; ...V }' is not assignable to type '{ ...T; ...U }'. + const atEnd: { ...T, ...U, second: string } = { ...t, ...u, second: 'foo' }; // ok + const atBeginning: { first: string, ...T, ...U, } = { first: 'foo', ...t, ...u }; // ok + + const emptyTarget: { } = { ...t, ...u } // ok + const emptySource: { ...T, ...U } = { }; // error, {} is not assignable to U (or T) + ~~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type '{ ...T; ...U }'. + + let optionalNumber: { sn?: number }; + let optionalString: { sn?: string }; + let optionalBoolean: { sn?: boolean }; + const unionCutoff: { ...T, sn?: number | string | boolean } = + { ...optionalBoolean, ...t, ...optionalString, ...optionalNumber } // ok + unionCutoff.sn; // ok + const optionalCutoff = { ...t, ...optionalNumber }; // ok + optionalCutoff.sn; // ok + + const interspersed: { first: string, ...T, second: string, ...U, third: string } = + { first: '1', ...t, second: '2', ...u, third: '3' }; // ok + const interspersedMissingU: { first: string, second: string, ...T, third: string } = + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ first: string; ...T; second: string; ...U; third: string; }' is not assignable to type '{ first: string; second: string; ...T; third: string; }'. + { first: '1', ...t, second: '2', ...u, third: '3' }; // error, 'U' is missing + const interspersedOrder1: { first: string, ...T, second: string, ...U, third: string, secondsecond: string } = + { first: '1', ...t, second: '2', ...u, third: '3', secondsecond: 'false' }; // ok + const interspersedOrder2: { first: string, second: string, secondsecond: string, third: string, ...T, ...U } = + { first: '1', ...t, second: '2', ...u, third: '3', secondsecond: 'false' }; // ok + + + const mismatchFirst: { first: string, ...T, second: string, ...U, third: string } = + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ firrrrrrst: string; ...T; second: string; ...U; third: string; }' is not assignable to type '{ first: string; ...T; second: string; ...U; third: string; }'. +!!! error TS2322: Property 'first' is missing in type '{ firrrrrrst: string; ...T; second: string; ...U; third: string; }'. + { firrrrrrst: '1', ...t, second: '2', ...u, third: '3' }; // error, 'first' not found + const mismatchSecond: { first: string, ...T, second: string, ...U, third: string } = + ~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ first: string; ...T; ssssssssecond: string; ...U; third: string; }' is not assignable to type '{ first: string; ...T; second: string; ...U; third: string; }'. +!!! error TS2322: Property 'second' is missing in type '{ first: string; ...T; ssssssssecond: string; ...U; third: string; }'. + { first: '1', ...t, ssssssssecond: '2', ...u, third: '3' }; // error, 'second' not found + const mismatchLast: { first: string, ...T, second: string, ...U, third: string } = + ~~~~~~~~~~~~ +!!! error TS2322: Type '{ first: string; ...T; second: string; ...U; thirrrrrrrd: string; }' is not assignable to type '{ first: string; ...T; second: string; ...U; third: string; }'. +!!! error TS2322: Property 'third' is missing in type '{ first: string; ...T; second: string; ...U; thirrrrrrrd: string; }'. + { first: '1', ...t, second: '2', ...u, thirrrrrrrd: '3' }; // error, 'third' not found + } + \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadGeneric.js b/tests/baselines/reference/objectSpreadGeneric.js new file mode 100644 index 00000000000..593ab73f98f --- /dev/null +++ b/tests/baselines/reference/objectSpreadGeneric.js @@ -0,0 +1,79 @@ +//// [objectSpreadGeneric.ts] +function f(t: T, u: U, v: V): void { + let o: { ...T, ...U, ...V }; + const same: { ...T, ...U, ...V } = o; // ok + const reversed: { ...V, ...U, ...T } = o; // error, reversed + const reversed2: { ...U, ...T, ...V } = o; // error, U and T are still reversed + const missingT: { ...U, ...V } = o; // error, missing T + const missingU: { ...T, ...V } = o; // error, missing U + const missingV: { ...T, ...U } = o; // error, missing V + const atEnd: { ...T, ...U, second: string } = { ...t, ...u, second: 'foo' }; // ok + const atBeginning: { first: string, ...T, ...U, } = { first: 'foo', ...t, ...u }; // ok + + const emptyTarget: { } = { ...t, ...u } // ok + const emptySource: { ...T, ...U } = { }; // error, {} is not assignable to U (or T) + + let optionalNumber: { sn?: number }; + let optionalString: { sn?: string }; + let optionalBoolean: { sn?: boolean }; + const unionCutoff: { ...T, sn?: number | string | boolean } = + { ...optionalBoolean, ...t, ...optionalString, ...optionalNumber } // ok + unionCutoff.sn; // ok + const optionalCutoff = { ...t, ...optionalNumber }; // ok + optionalCutoff.sn; // ok + + const interspersed: { first: string, ...T, second: string, ...U, third: string } = + { first: '1', ...t, second: '2', ...u, third: '3' }; // ok + const interspersedMissingU: { first: string, second: string, ...T, third: string } = + { first: '1', ...t, second: '2', ...u, third: '3' }; // error, 'U' is missing + const interspersedOrder1: { first: string, ...T, second: string, ...U, third: string, secondsecond: string } = + { first: '1', ...t, second: '2', ...u, third: '3', secondsecond: 'false' }; // ok + const interspersedOrder2: { first: string, second: string, secondsecond: string, third: string, ...T, ...U } = + { first: '1', ...t, second: '2', ...u, third: '3', secondsecond: 'false' }; // ok + + + const mismatchFirst: { first: string, ...T, second: string, ...U, third: string } = + { firrrrrrst: '1', ...t, second: '2', ...u, third: '3' }; // error, 'first' not found + const mismatchSecond: { first: string, ...T, second: string, ...U, third: string } = + { first: '1', ...t, ssssssssecond: '2', ...u, third: '3' }; // error, 'second' not found + const mismatchLast: { first: string, ...T, second: string, ...U, third: string } = + { first: '1', ...t, second: '2', ...u, thirrrrrrrd: '3' }; // error, 'third' not found +} + + +//// [objectSpreadGeneric.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +function f(t, u, v) { + var o; + var same = o; // ok + var reversed = o; // error, reversed + var reversed2 = o; // error, U and T are still reversed + var missingT = o; // error, missing T + var missingU = o; // error, missing U + var missingV = o; // error, missing V + var atEnd = __assign({}, t, u, { second: 'foo' }); // ok + var atBeginning = __assign({ first: 'foo' }, t, u); // ok + var emptyTarget = __assign({}, t, u); // ok + var emptySource = {}; // error, {} is not assignable to U (or T) + var optionalNumber; + var optionalString; + var optionalBoolean; + var unionCutoff = __assign({}, optionalBoolean, t, optionalString, optionalNumber); // ok + unionCutoff.sn; // ok + var optionalCutoff = __assign({}, t, optionalNumber); // ok + optionalCutoff.sn; // ok + var interspersed = __assign({ first: '1' }, t, { second: '2' }, u, { third: '3' }); // ok + var interspersedMissingU = __assign({ first: '1' }, t, { second: '2' }, u, { third: '3' }); // error, 'U' is missing + var interspersedOrder1 = __assign({ first: '1' }, t, { second: '2' }, u, { third: '3', secondsecond: 'false' }); // ok + var interspersedOrder2 = __assign({ first: '1' }, t, { second: '2' }, u, { third: '3', secondsecond: 'false' }); // ok + var mismatchFirst = __assign({ firrrrrrst: '1' }, t, { second: '2' }, u, { third: '3' }); // error, 'first' not found + var mismatchSecond = __assign({ first: '1' }, t, { ssssssssecond: '2' }, u, { third: '3' }); // error, 'second' not found + var mismatchLast = __assign({ first: '1' }, t, { second: '2' }, u, { thirrrrrrrd: '3' }); // error, 'third' not found +} diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt new file mode 100644 index 00000000000..1ee3acb823c --- /dev/null +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -0,0 +1,93 @@ +tests/cases/conformance/types/spread/objectSpreadNegative.ts(13,30): error TS2339: Property 'x' does not exist on type '{ ...PublicX; ...PrivateOptionalX }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(16,5): error TS2322: Type '{ ...{ sn?: string; }; ...{ sn?: number; } }' is not assignable to type '{ sn: string | number; }'. + Property 'sn' is optional in type '{ ...{ sn?: string; }; ...{ sn?: number; } }' but required in type '{ sn: string | number; }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(22,5): error TS2322: Type '{ s: string; }' is not assignable to type '{ ...Bool; ...Str }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(24,1): error TS2322: Type 'Bool' is not assignable to type '{ ...Bool; ...Str }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(27,15): error TS2697: Spread properties must be identifiers, property accesses, or object literals. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,15): error TS2697: Spread properties must be identifiers, property accesses, or object literals. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(31,36): error TS2300: Duplicate identifier 'b'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(31,53): error TS2300: Duplicate identifier 'b'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(36,12): error TS2339: Property 'b' does not exist on type '{ ...{ b: number; } }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,9): error TS2339: Property 'm' does not exist on type '{ ...C }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(45,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ ...PublicX }' has no compatible call signatures. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(46,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(48,39): error TS2697: Spread properties must be identifiers, property accesses, or object literals. + + +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (13 errors) ==== + let o = { a: 1, b: 'no' } + + /// private propagates + class PrivateOptionalX { + private x?: number; + } + class PublicX { + public x: number; + } + let privateOptionalx: PrivateOptionalX; + let publicx: PublicX; + let o3 = { ...publicx, ...privateOptionalx }; + let sn: string | number = o3.x; // error, x is private + ~ +!!! error TS2339: Property 'x' does not exist on type '{ ...PublicX; ...PrivateOptionalX }'. + let optionalString: { sn?: string }; + let optionalNumber: { sn?: number }; + let allOptional: { sn: string | number } = { ...optionalString, ...optionalNumber }; + ~~~~~~~~~~~ +!!! error TS2322: Type '{ ...{ sn?: string; }; ...{ sn?: number; } }' is not assignable to type '{ sn: string | number; }'. +!!! error TS2322: Property 'sn' is optional in type '{ ...{ sn?: string; }; ...{ sn?: number; } }' but required in type '{ sn: string | number; }'. + // error, 'sn' is optional in source, required in target + + // assignability as target + interface Bool { b: boolean }; + interface Str { s: string }; + let spread: { ...Bool, ...Str } = { s: 'foo' }; // error, missing 'b' + ~~~~~~ +!!! error TS2322: Type '{ s: string; }' is not assignable to type '{ ...Bool; ...Str }'. + let b: Bool; + spread = b; // error, missing 's' + ~~~~~~ +!!! error TS2322: Type 'Bool' is not assignable to type '{ ...Bool; ...Str }'. + + // 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' } + ~ +!!! error TS2300: Duplicate identifier 'b'. + ~ +!!! error TS2300: Duplicate identifier 'b'. + let duplicatedSpread = { ...o, ...o } + + // write-only properties get skipped + let setterOnly = { ...{ set b (bad: number) { } } }; + setterOnly.b = 12; // error, 'b' does not exist + ~ +!!! error TS2339: Property 'b' does not exist on type '{ ...{ b: number; } }'. + + // methods are skipped because they aren't enumerable + class C { p = 1; m() { } } + let c: C = new C() + let spreadC = { ...c } + spreadC.m(); // error 'm' is not in '{ ... c }' + ~ +!!! error TS2339: Property 'm' does not exist on type '{ ...C }'. + + let callableConstructableSpread: { ...PublicX, (n: number): number, new (p: number) }; + callableConstructableSpread(12); // error, no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ ...PublicX }' has no compatible call signatures. + new callableConstructableSpread(12); // error, no construct signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + let callableSpread = { ...publicx, ...(n => n + 1) }; // error, can't spread functions + ~~~~~~~~~~~~ +!!! error TS2697: Spread properties must be identifiers, property accesses, or object literals. + \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js new file mode 100644 index 00000000000..685760f9444 --- /dev/null +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -0,0 +1,108 @@ +//// [objectSpreadNegative.ts] +let o = { a: 1, b: 'no' } + +/// private propagates +class PrivateOptionalX { + private x?: number; +} +class PublicX { + public x: number; +} +let privateOptionalx: PrivateOptionalX; +let publicx: PublicX; +let o3 = { ...publicx, ...privateOptionalx }; +let sn: string | number = o3.x; // error, x is private +let optionalString: { sn?: string }; +let optionalNumber: { sn?: number }; +let allOptional: { sn: string | number } = { ...optionalString, ...optionalNumber }; +// error, 'sn' is optional in source, required in target + +// assignability as target +interface Bool { b: boolean }; +interface Str { s: string }; +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 } + +// write-only properties get skipped +let setterOnly = { ...{ set b (bad: number) { } } }; +setterOnly.b = 12; // error, 'b' does not exist + +// methods are skipped because they aren't enumerable +class C { p = 1; m() { } } +let c: C = new C() +let spreadC = { ...c } +spreadC.m(); // error 'm' is not in '{ ... c }' + +let callableConstructableSpread: { ...PublicX, (n: number): number, new (p: number) }; +callableConstructableSpread(12); // error, no call signature +new callableConstructableSpread(12); // error, no construct signature + +let callableSpread = { ...publicx, ...(n => n + 1) }; // error, can't spread functions + + +//// [objectSpreadNegative.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 o = { a: 1, b: 'no' }; +/// private propagates +var PrivateOptionalX = (function () { + function PrivateOptionalX() { + } + return PrivateOptionalX; +}()); +var PublicX = (function () { + function PublicX() { + } + return PublicX; +}()); +var privateOptionalx; +var publicx; +var o3 = __assign({}, publicx, privateOptionalx); +var sn = o3.x; // error, x is private +var optionalString; +var optionalNumber; +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); +// write-only properties get skipped +var setterOnly = __assign({ set b(bad: number) { } }); +setterOnly.b = 12; // error, 'b' does not exist +// methods are skipped because they aren't enumerable +var C = (function () { + function C() { + this.p = 1; + } + C.prototype.m = function () { }; + return C; +}()); +var c = new C(); +var spreadC = __assign({}, c); +spreadC.m(); // error 'm' is not in '{ ... c }' +var callableConstructableSpread; +callableConstructableSpread(12); // error, no call signature +new callableConstructableSpread(12); // error, no construct signature +var callableSpread = __assign({}, publicx, (function (n) { return n + 1; })); // error, can't spread functions diff --git a/tests/baselines/reference/objectSpreadNegativeParse.errors.txt b/tests/baselines/reference/objectSpreadNegativeParse.errors.txt new file mode 100644 index 00000000000..41651fb1d1c --- /dev/null +++ b/tests/baselines/reference/objectSpreadNegativeParse.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(1,15): error TS2304: Cannot find name 'o'. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(1,18): error TS1109: Expression expected. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(2,15): error TS1109: Expression expected. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(2,16): error TS2304: Cannot find name 'o'. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(3,15): error TS2304: Cannot find name 'matchMedia'. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(3,28): error TS1005: ',' expected. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(3,31): error TS1128: Declaration or statement expected. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(4,16): error TS2304: Cannot find name 'get'. +tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts(4,20): error TS1005: ',' expected. + + +==== tests/cases/conformance/types/spread/objectSpreadNegativeParse.ts (9 errors) ==== + let o7 = { ...o? }; + ~ +!!! error TS2304: Cannot find name 'o'. + ~ +!!! error TS1109: Expression expected. + let o8 = { ...*o }; + ~ +!!! error TS1109: Expression expected. + ~ +!!! error TS2304: Cannot find name 'o'. + let o9 = { ...matchMedia() { }}; + ~~~~~~~~~~ +!!! error TS2304: Cannot find name 'matchMedia'. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS1128: Declaration or statement expected. + let o10 = { ...get x() { return 12; }}; + ~~~ +!!! error TS2304: Cannot find name 'get'. + ~ +!!! error TS1005: ',' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadNegativeParse.js b/tests/baselines/reference/objectSpreadNegativeParse.js new file mode 100644 index 00000000000..297c56c3e62 --- /dev/null +++ b/tests/baselines/reference/objectSpreadNegativeParse.js @@ -0,0 +1,21 @@ +//// [objectSpreadNegativeParse.ts] +let o7 = { ...o? }; +let o8 = { ...*o }; +let o9 = { ...matchMedia() { }}; +let o10 = { ...get x() { return 12; }}; + + +//// [objectSpreadNegativeParse.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 o7 = __assign({}, o ? : ); +var o8 = __assign({}, * o); +var o9 = __assign({}, matchMedia()), _a = void 0; +; +var o10 = __assign({}, get, { x: function () { return 12; } });