diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a3bd27bfa210b..fcd4bc68a55c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11164,10 +11164,10 @@ namespace ts { return links.resolvedType; } - function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, properties: Symbol[], kind: IndexKind): IndexInfo { + function getObjectLiteralIndexInfo(propertyNodes: NodeArray, offset: number, properties: Symbol[], kind: IndexKind): IndexInfo { const propTypes: Type[] = []; for (let i = 0; i < properties.length; i++) { - if (kind === IndexKind.String || isNumericName(node.properties[i].name)) { + if (kind === IndexKind.String || isNumericName(propertyNodes[i + offset].name)) { propTypes.push(getTypeOfSymbol(properties[i])); } } @@ -11193,7 +11193,9 @@ namespace ts { let hasComputedStringProperty = false; let hasComputedNumberProperty = false; - for (const memberDecl of node.properties) { + let offset = 0; + for (let i = 0; i < node.properties.length; i++) { + const memberDecl = node.properties[i]; let member = memberDecl.symbol; if (memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment || @@ -11262,6 +11264,7 @@ namespace ts { return unknownType; } spread = getSpreadType(spread, type, /*isFromObjectLiteral*/ false); + offset = i + 1; continue; } else { @@ -11315,8 +11318,8 @@ namespace ts { return createObjectLiteralType(); function createObjectLiteralType() { - const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.String) : undefined; - const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.Number) : undefined; + const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.String) : undefined; + const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.Number) : undefined; const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral; result.flags |= TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a18146bdaa1fa..eacfd1f0b678f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -38,6 +38,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; };`; @@ -45,8 +48,11 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { const restHelper = ` var __rest = (this && this.__rest) || function (s, e) { var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p)) + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; return t; };`; diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index a8c007767412f..4e56cb71a122c 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -304,17 +304,19 @@ namespace ts { if (properties.length !== 1) { // For anything but a single element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. - // When doing so we want to hightlight the passed in source map node since thats the one needing this temp assignment + // When doing so we want to highlight the passed in source map node since that's the one needing this temp assignment value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment); } let bindingElements: ObjectLiteralElementLike[] = []; + let computedTempVariables: Expression[]; for (let i = 0; i < properties.length; i++) { const p = properties[i]; if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { if (!transformRest || p.transformFlags & TransformFlags.ContainsSpreadExpression || - (p.kind === SyntaxKind.PropertyAssignment && p.initializer.transformFlags & TransformFlags.ContainsSpreadExpression)) { + (p.kind === SyntaxKind.PropertyAssignment && p.initializer.transformFlags & TransformFlags.ContainsSpreadExpression) || + isComputedPropertyName(p.name)) { if (bindingElements.length) { emitRestAssignment(bindingElements, value, location, target); bindingElements = []; @@ -322,7 +324,11 @@ namespace ts { const propName = (p).name; const bindingTarget = p.kind === SyntaxKind.ShorthandPropertyAssignment ? p : (p).initializer || propName; // Assignment for bindingTarget = value.propName should highlight whole property, hence use p as source map node - emitDestructuringAssignment(bindingTarget, createDestructuringPropertyAccess(value, propName), p); + const propAccess = createDestructuringPropertyAccess(value, propName); + if (isComputedPropertyName(propName)) { + computedTempVariables = append(computedTempVariables, (propAccess as ElementAccessExpression).argumentExpression); + } + emitDestructuringAssignment(bindingTarget, propAccess, p); } else { bindingElements.push(p); @@ -336,7 +342,7 @@ namespace ts { bindingElements = []; } const propName = (p as SpreadAssignment).expression as Identifier; - const restCall = createRestCall(value, target.properties, p => p.name, target); + const restCall = createRestCall(value, target.properties, p => p.name, target, computedTempVariables); emitDestructuringAssignment(propName, restCall, p); } } @@ -413,17 +419,28 @@ namespace ts { /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`*/ - function createRestCall(value: Expression, elements: T[], getPropertyName: (element: T) => PropertyName, location: TextRange): Expression { - const propertyNames: LiteralExpression[] = []; + function createRestCall(value: Expression, elements: T[], getPropertyName: (element: T) => PropertyName, location: TextRange, computedTempVariables: Expression[]): Expression { + const propertyNames: Expression[] = []; for (let i = 0; i < elements.length - 1; i++) { - if (isOmittedExpression(elements[i])) { + const element = elements[i]; + if (isOmittedExpression(element)) { continue; } - const str = createSynthesizedNode(SyntaxKind.StringLiteral); - str.pos = location.pos; - str.end = location.end; - str.text = getTextOfPropertyName(getPropertyName(elements[i])); - propertyNames.push(str); + if (isComputedPropertyName(getPropertyName(element))) { + // get the temp name and put that in there instead, like `_tmp + ""` + const temp = computedTempVariables.shift(); + propertyNames.push(createConditional(createBinary(createTypeOf(temp), + SyntaxKind.EqualsEqualsEqualsToken, + createLiteral("symbol")), + createToken(SyntaxKind.QuestionToken), + temp, + createToken(SyntaxKind.ColonToken), + createBinary(temp, SyntaxKind.PlusToken, createLiteral("")))); + } + else { + const propName = getTextOfPropertyName(getPropertyName(element)); + propertyNames.push(createLiteral(propName, location)); + } } const args = createSynthesizedNodeArray([value, createArrayLiteral(propertyNames, location)]); return createCall(createIdentifier("__rest"), undefined, args); @@ -522,6 +539,7 @@ namespace ts { const elements = name.elements; const numElements = elements.length; let bindingElements: BindingElement[] = []; + let computedTempVariables: Expression[]; for (let i = 0; i < numElements; i++) { const element = elements[i]; if (isOmittedExpression(element)) { @@ -533,12 +551,15 @@ namespace ts { bindingElements = []; } const restCall = createRestCall(value, - name.elements, + elements, // name.elements, element => (element as BindingElement).propertyName || (element as BindingElement).name, - name); + name, + computedTempVariables); emitBindingElement(element, restCall); } - else if (transformRest && !(element.transformFlags & TransformFlags.ContainsSpreadExpression)) { + else if (transformRest && + !(element.transformFlags & TransformFlags.ContainsSpreadExpression) && + !isComputedPropertyName(element.propertyName || element.name)) { // do not emit until we have a complete bundle of ES2015 syntax bindingElements.push(element); } @@ -549,7 +570,11 @@ namespace ts { } // Rewrite element to a declaration with an initializer that fetches property const propName = element.propertyName || element.name; - emitBindingElement(element, createDestructuringPropertyAccess(value, propName)); + const propAccess = createDestructuringPropertyAccess(value, propName); + if (isComputedPropertyName(propName)) { + computedTempVariables = append(computedTempVariables, (propAccess as ElementAccessExpression).argumentExpression); + } + emitBindingElement(element, propAccess); } } if (bindingElements.length) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a9f2429d37645..ed15264ba16f9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1262,6 +1262,7 @@ namespace ts { case SyntaxKind.Decorator: case SyntaxKind.JsxExpression: case SyntaxKind.JsxSpreadAttribute: + case SyntaxKind.SpreadAssignment: return true; case SyntaxKind.ExpressionWithTypeArguments: return (parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent); diff --git a/tests/baselines/reference/importHelpersInTsx.js b/tests/baselines/reference/importHelpersInTsx.js index 29e43e191e8aa..d1fe0df2c5146 100644 --- a/tests/baselines/reference/importHelpersInTsx.js +++ b/tests/baselines/reference/importHelpersInTsx.js @@ -29,6 +29,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/objectRest.js b/tests/baselines/reference/objectRest.js index a295ff7b9f1a2..2144fb9271c2b 100644 --- a/tests/baselines/reference/objectRest.js +++ b/tests/baselines/reference/objectRest.js @@ -1,5 +1,5 @@ //// [objectRest.ts] -let o = { a: 1, b: 'no' } +var o = { a: 1, b: 'no' } var { ...clone } = o; var { a, ...justB } = o; var { a, b: renamed, ...empty } = o; @@ -31,31 +31,39 @@ class Removable { } var removable = new Removable(); var { removed, ...removableRest } = removable; + +let computed = 'b'; +let computed2 = 'a'; +var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; +({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); //// [objectRest.js] var __rest = (this && this.__rest) || function (s, e) { var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p)) + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; return t; }; -let o = { a: 1, b: 'no' }; +var o = { a: 1, b: 'no' }; var clone = __rest(o, []); var { a } = o, justB = __rest(o, ["a"]); var { a, b: renamed } = o, empty = __rest(o, ["a", "b"]); -var { ['b']: renamed } = o, justA = __rest(o, ["b"]); +var _a = 'b', renamed = o[_a], justA = __rest(o, [typeof _a === "symbol" ? _a : _a + ""]); var { 'b': renamed } = o, justA = __rest(o, ["b"]); var { b: { '0': n, '1': oooo } } = o, justA = __rest(o, ["b"]); let o2 = { c: 'terrible idea?', d: 'yes' }; var { d: renamed } = o2, d = __rest(o2, ["d"]); let nestedrest; -var { x } = nestedrest, _a = nestedrest.n1, { y } = _a, _b = _a.n2, { z } = _b, nr = __rest(_b.n3, []), restrest = __rest(nestedrest, ["x", "n1"]); +var { x } = nestedrest, _b = nestedrest.n1, { y } = _b, _c = _b.n2, { z } = _c, nr = __rest(_c.n3, []), restrest = __rest(nestedrest, ["x", "n1"]); let complex; -var _c = complex.x, { ka } = _c, nested = __rest(_c, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]); -(_d = complex.x, { ka } = _d, nested = __rest(_d, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]), complex); -var _e = { x: 1, y: 2 }, { x } = _e, fresh = __rest(_e, ["x"]); -(_f = { x: 1, y: 2 }, { x } = _f, fresh = __rest(_f, ["x"]), _f); +var _d = complex.x, { ka } = _d, nested = __rest(_d, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]); +(_e = complex.x, { ka } = _e, nested = __rest(_e, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]), complex); +var _f = { x: 1, y: 2 }, { x } = _f, fresh = __rest(_f, ["x"]); +(_g = { x: 1, y: 2 }, { x } = _g, fresh = __rest(_g, ["x"]), _g); class Removable { set z(value) { } get both() { return 12; } @@ -64,4 +72,8 @@ class Removable { } var removable = new Removable(); var { removed } = removable, removableRest = __rest(removable, ["removed"]); -var _d, _f; +let computed = 'b'; +let computed2 = 'a'; +var _h = computed, stillNotGreat = o[_h], _j = computed2, soSo = o[_j], o = __rest(o, [typeof _h === "symbol" ? _h : _h + "", typeof _j === "symbol" ? _j : _j + ""]); +(_k = computed, stillNotGreat = o[_k], _l = computed2, soSo = o[_l], o = __rest(o, [typeof _k === "symbol" ? _k : _k + "", typeof _l === "symbol" ? _l : _l + ""]), o); +var _e, _g, _k, _l; diff --git a/tests/baselines/reference/objectRest.symbols b/tests/baselines/reference/objectRest.symbols index 427656248ee19..325258aa8cd6c 100644 --- a/tests/baselines/reference/objectRest.symbols +++ b/tests/baselines/reference/objectRest.symbols @@ -1,42 +1,42 @@ === tests/cases/conformance/types/rest/objectRest.ts === -let o = { a: 1, b: 'no' } ->o : Symbol(o, Decl(objectRest.ts, 0, 3)) +var o = { a: 1, b: 'no' } +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) >a : Symbol(a, Decl(objectRest.ts, 0, 9)) >b : Symbol(b, Decl(objectRest.ts, 0, 15)) var { ...clone } = o; >clone : Symbol(clone, Decl(objectRest.ts, 1, 5)) ->o : Symbol(o, Decl(objectRest.ts, 0, 3)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) var { a, ...justB } = o; >a : Symbol(a, Decl(objectRest.ts, 2, 5), Decl(objectRest.ts, 3, 5)) >justB : Symbol(justB, Decl(objectRest.ts, 2, 8)) ->o : Symbol(o, Decl(objectRest.ts, 0, 3)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) var { a, b: renamed, ...empty } = o; >a : Symbol(a, Decl(objectRest.ts, 2, 5), Decl(objectRest.ts, 3, 5)) >b : Symbol(b, Decl(objectRest.ts, 0, 15)) >renamed : Symbol(renamed, Decl(objectRest.ts, 3, 8), Decl(objectRest.ts, 4, 5), Decl(objectRest.ts, 5, 5), Decl(objectRest.ts, 9, 5)) >empty : Symbol(empty, Decl(objectRest.ts, 3, 20)) ->o : Symbol(o, Decl(objectRest.ts, 0, 3)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) var { ['b']: renamed, ...justA } = o; >'b' : Symbol(renamed, Decl(objectRest.ts, 3, 8), Decl(objectRest.ts, 4, 5), Decl(objectRest.ts, 5, 5), Decl(objectRest.ts, 9, 5)) >renamed : Symbol(renamed, Decl(objectRest.ts, 3, 8), Decl(objectRest.ts, 4, 5), Decl(objectRest.ts, 5, 5), Decl(objectRest.ts, 9, 5)) >justA : Symbol(justA, Decl(objectRest.ts, 4, 21), Decl(objectRest.ts, 5, 19), Decl(objectRest.ts, 6, 31)) ->o : Symbol(o, Decl(objectRest.ts, 0, 3)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) var { 'b': renamed, ...justA } = o; >renamed : Symbol(renamed, Decl(objectRest.ts, 3, 8), Decl(objectRest.ts, 4, 5), Decl(objectRest.ts, 5, 5), Decl(objectRest.ts, 9, 5)) >justA : Symbol(justA, Decl(objectRest.ts, 4, 21), Decl(objectRest.ts, 5, 19), Decl(objectRest.ts, 6, 31)) ->o : Symbol(o, Decl(objectRest.ts, 0, 3)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) var { b: { '0': n, '1': oooo }, ...justA } = o; >b : Symbol(b, Decl(objectRest.ts, 0, 15)) >n : Symbol(n, Decl(objectRest.ts, 6, 10)) >oooo : Symbol(oooo, Decl(objectRest.ts, 6, 18)) >justA : Symbol(justA, Decl(objectRest.ts, 4, 21), Decl(objectRest.ts, 5, 19), Decl(objectRest.ts, 6, 31)) ->o : Symbol(o, Decl(objectRest.ts, 0, 3)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) let o2 = { c: 'terrible idea?', d: 'yes' }; >o2 : Symbol(o2, Decl(objectRest.ts, 8, 3)) @@ -91,8 +91,10 @@ var { x: { ka, ...nested }, y: other, ...rest } = complex; ({x: { ka, ...nested }, y: other, ...rest} = complex); >x : Symbol(x, Decl(objectRest.ts, 16, 2)) >ka : Symbol(ka, Decl(objectRest.ts, 16, 6)) +>nested : Symbol(nested, Decl(objectRest.ts, 15, 14)) >y : Symbol(y, Decl(objectRest.ts, 16, 23)) >other : Symbol(other, Decl(objectRest.ts, 15, 27)) +>rest : Symbol(rest, Decl(objectRest.ts, 15, 37)) >complex : Symbol(complex, Decl(objectRest.ts, 14, 3)) var { x, ...fresh } = { x: 1, y: 2 }; @@ -103,6 +105,7 @@ var { x, ...fresh } = { x: 1, y: 2 }; ({ x, ...fresh } = { x: 1, y: 2 }); >x : Symbol(x, Decl(objectRest.ts, 18, 2)) +>fresh : Symbol(fresh, Decl(objectRest.ts, 17, 8)) >x : Symbol(x, Decl(objectRest.ts, 18, 20)) >y : Symbol(y, Decl(objectRest.ts, 18, 26)) @@ -144,3 +147,25 @@ var { removed, ...removableRest } = removable; >removableRest : Symbol(removableRest, Decl(objectRest.ts, 31, 14)) >removable : Symbol(removable, Decl(objectRest.ts, 30, 3)) +let computed = 'b'; +>computed : Symbol(computed, Decl(objectRest.ts, 33, 3)) + +let computed2 = 'a'; +>computed2 : Symbol(computed2, Decl(objectRest.ts, 34, 3)) + +var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; +>computed : Symbol(computed, Decl(objectRest.ts, 33, 3)) +>stillNotGreat : Symbol(stillNotGreat, Decl(objectRest.ts, 35, 5)) +>computed2 : Symbol(computed2, Decl(objectRest.ts, 34, 3)) +>soSo : Symbol(soSo, Decl(objectRest.ts, 35, 32)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) + +({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); +>computed : Symbol(computed, Decl(objectRest.ts, 33, 3)) +>stillNotGreat : Symbol(stillNotGreat, Decl(objectRest.ts, 35, 5)) +>computed2 : Symbol(computed2, Decl(objectRest.ts, 34, 3)) +>soSo : Symbol(soSo, Decl(objectRest.ts, 35, 32)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) +>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) + diff --git a/tests/baselines/reference/objectRest.types b/tests/baselines/reference/objectRest.types index 95e378359c8ba..7d8335437472f 100644 --- a/tests/baselines/reference/objectRest.types +++ b/tests/baselines/reference/objectRest.types @@ -1,5 +1,5 @@ === tests/cases/conformance/types/rest/objectRest.ts === -let o = { a: 1, b: 'no' } +var o = { a: 1, b: 'no' } >o : { a: number; b: string; } >{ a: 1, b: 'no' } : { a: number; b: string; } >a : number @@ -101,10 +101,10 @@ var { x: { ka, ...nested }, y: other, ...rest } = complex; >x : { ki: any; ka: any; } >{ ka, ...nested } : { ki: any; ka: any; } >ka : any ->nested : any +>nested : { ki: any; } >y : number >other : number ->rest : any +>rest : {} >complex : { x: { ka: any; ki: any; }; y: number; } var { x, ...fresh } = { x: 1, y: 2 }; @@ -121,7 +121,7 @@ var { x, ...fresh } = { x: 1, y: 2 }; >{ x, ...fresh } = { x: 1, y: 2 } : { x: number; y: number; } >{ x, ...fresh } : { y: number; x: number; } >x : number ->fresh : any +>fresh : { y: number; } >{ x: 1, y: 2 } : { x: number; y: number; } >x : number >1 : 1 @@ -168,3 +168,30 @@ var { removed, ...removableRest } = removable; >removableRest : { both: number; remainder: string; } >removable : Removable +let computed = 'b'; +>computed : string +>'b' : "b" + +let computed2 = 'a'; +>computed2 : string +>'a' : "a" + +var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; +>computed : string +>stillNotGreat : any +>computed2 : string +>soSo : any +>o : { a: number; b: string; } +>o : { a: number; b: string; } + +({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); +>({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o) : { a: number; b: string; } +>{ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o : { a: number; b: string; } +>{ [computed]: stillNotGreat, [computed2]: soSo, ...o } : { a: number; b: string; } +>computed : string +>stillNotGreat : any +>computed2 : string +>soSo : any +>o : { a: number; b: string; } +>o : { a: number; b: string; } + diff --git a/tests/baselines/reference/objectRest2.js b/tests/baselines/reference/objectRest2.js index e21c8c79853e0..5e3f17b857f55 100644 --- a/tests/baselines/reference/objectRest2.js +++ b/tests/baselines/reference/objectRest2.js @@ -20,6 +20,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/objectRestAssignment.js b/tests/baselines/reference/objectRestAssignment.js index 41620d59b584f..7aec259c69bb8 100644 --- a/tests/baselines/reference/objectRestAssignment.js +++ b/tests/baselines/reference/objectRestAssignment.js @@ -17,8 +17,11 @@ var { a: [{ ...nested2 }, ...y], b: { z, ...c }, ...rest2 } = overEmit; //// [objectRestAssignment.js] var __rest = (this && this.__rest) || function (s, e) { var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p)) + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; return t; }; let ka; diff --git a/tests/baselines/reference/objectRestAssignment.symbols b/tests/baselines/reference/objectRestAssignment.symbols index 4cb27e6e7ecd6..82324873283c1 100644 --- a/tests/baselines/reference/objectRestAssignment.symbols +++ b/tests/baselines/reference/objectRestAssignment.symbols @@ -22,8 +22,10 @@ let complex: { x: { ka, ki }, y: number }; ({x: { ka, ...nested }, y: other, ...rest} = complex); >x : Symbol(x, Decl(objectRestAssignment.ts, 5, 2)) >ka : Symbol(ka, Decl(objectRestAssignment.ts, 5, 6)) +>nested : Symbol(nested, Decl(objectRestAssignment.ts, 1, 3)) >y : Symbol(y, Decl(objectRestAssignment.ts, 5, 23)) >other : Symbol(other, Decl(objectRestAssignment.ts, 2, 3)) +>rest : Symbol(rest, Decl(objectRestAssignment.ts, 3, 3)) >complex : Symbol(complex, Decl(objectRestAssignment.ts, 4, 3)) // should be: @@ -52,8 +54,11 @@ var { a: [{ ...nested2 }, ...y], b: { z, ...c }, ...rest2 } = overEmit; ({ a: [{ ...nested2 }, ...y], b: { z, ...c }, ...rest2 } = overEmit); >a : Symbol(a, Decl(objectRestAssignment.ts, 12, 2)) +>nested2 : Symbol(nested2, Decl(objectRestAssignment.ts, 11, 11)) >y : Symbol(y, Decl(objectRestAssignment.ts, 11, 25)) >b : Symbol(b, Decl(objectRestAssignment.ts, 12, 29)) >z : Symbol(z, Decl(objectRestAssignment.ts, 12, 34)) +>c : Symbol(c, Decl(objectRestAssignment.ts, 11, 40)) +>rest2 : Symbol(rest2, Decl(objectRestAssignment.ts, 11, 48)) >overEmit : Symbol(overEmit, Decl(objectRestAssignment.ts, 8, 3)) diff --git a/tests/baselines/reference/objectRestAssignment.types b/tests/baselines/reference/objectRestAssignment.types index 38aa00ce61dc4..b51260736ade0 100644 --- a/tests/baselines/reference/objectRestAssignment.types +++ b/tests/baselines/reference/objectRestAssignment.types @@ -26,10 +26,10 @@ let complex: { x: { ka, ki }, y: number }; >x : { ki: any; ka: any; } >{ ka, ...nested } : { ki: any; ka: any; } >ka : any ->nested : any +>nested : { ki: any; } >y : number >other : number ->rest : any +>rest : {} >complex : { x: { ka: any; ki: any; }; y: number; } // should be: @@ -63,13 +63,13 @@ var { a: [{ ...nested2 }, ...y], b: { z, ...c }, ...rest2 } = overEmit; >a : { ka: string; x: string; }[] >[{ ...nested2 }, ...y] : { ka: string; x: string; }[] >{ ...nested2 } : { ka: string; x: string; } ->nested2 : any +>nested2 : { ka: string; x: string; } >...y : { ka: string; x: string; } >y : { ka: string; x: string; }[] >b : { ki: string; ku: string; z: string; } >{ z, ...c } : { ki: string; ku: string; z: string; } >z : string ->c : any ->rest2 : any +>c : { ki: string; ku: string; } +>rest2 : { ke: string; ko: string; } >overEmit : { a: { ka: string; x: string; }[]; b: { z: string; ki: string; ku: string; }; ke: string; ko: string; } diff --git a/tests/baselines/reference/objectRestForOf.js b/tests/baselines/reference/objectRestForOf.js index 26ebd8f8229c5..0fa589737bfa3 100644 --- a/tests/baselines/reference/objectRestForOf.js +++ b/tests/baselines/reference/objectRestForOf.js @@ -20,13 +20,19 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p)) + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; return t; }; let array; diff --git a/tests/baselines/reference/objectRestForOf.symbols b/tests/baselines/reference/objectRestForOf.symbols index ec0ccde740d5b..f3786fed55fbc 100644 --- a/tests/baselines/reference/objectRestForOf.symbols +++ b/tests/baselines/reference/objectRestForOf.symbols @@ -23,6 +23,7 @@ let rrestOff: { y: string }; for ({ x: xx, ...rrestOff } of array ) { >x : Symbol(x, Decl(objectRestForOf.ts, 6, 6)) >xx : Symbol(xx, Decl(objectRestForOf.ts, 4, 3)) +>rrestOff : Symbol(rrestOff, Decl(objectRestForOf.ts, 5, 3)) >array : Symbol(array, Decl(objectRestForOf.ts, 0, 3)) [xx, rrestOff]; @@ -35,6 +36,7 @@ for (const norest of array.map(a => ({ ...a, x: 'a string' }))) { >array : Symbol(array, Decl(objectRestForOf.ts, 0, 3)) >map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >a : Symbol(a, Decl(objectRestForOf.ts, 9, 31)) +>a : Symbol(a, Decl(objectRestForOf.ts, 9, 31)) >x : Symbol(x, Decl(objectRestForOf.ts, 9, 44)) [norest.x, norest.y]; diff --git a/tests/baselines/reference/objectRestForOf.types b/tests/baselines/reference/objectRestForOf.types index e8c3b4a82abf1..2fde7566c745f 100644 --- a/tests/baselines/reference/objectRestForOf.types +++ b/tests/baselines/reference/objectRestForOf.types @@ -25,7 +25,7 @@ for ({ x: xx, ...rrestOff } of array ) { >{ x: xx, ...rrestOff } : { y: string; x: number; } >x : { x: number; y: string; } >xx : number ->rrestOff : any +>rrestOff : { y: string; } >array : { x: number; y: string; }[] [xx, rrestOff]; @@ -43,7 +43,7 @@ for (const norest of array.map(a => ({ ...a, x: 'a string' }))) { >a : { x: number; y: string; } >({ ...a, x: 'a string' }) : { x: string; y: string; } >{ ...a, x: 'a string' } : { x: string; y: string; } ->a : any +>a : { x: number; y: string; } >x : string >'a string' : "a string" diff --git a/tests/baselines/reference/objectRestNegative.js b/tests/baselines/reference/objectRestNegative.js index 8692850dbdd33..22af1f8715bff 100644 --- a/tests/baselines/reference/objectRestNegative.js +++ b/tests/baselines/reference/objectRestNegative.js @@ -15,8 +15,11 @@ let rest: { b: string } //// [objectRestNegative.js] var __rest = (this && this.__rest) || function (s, e) { var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p)) + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; return t; }; var o = { a: 1, b: 'no' }; diff --git a/tests/baselines/reference/objectRestParameter.js b/tests/baselines/reference/objectRestParameter.js index 49434f24eece7..f724113548648 100644 --- a/tests/baselines/reference/objectRestParameter.js +++ b/tests/baselines/reference/objectRestParameter.js @@ -11,8 +11,11 @@ suddenly(({ x: { z = 12, ...nested }, ...rest } = { x: { z: 1, ka: 1 }, y: 'noo' //// [objectRestParameter.js] var __rest = (this && this.__rest) || function (s, e) { var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p)) + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; return t; }; function cloneAgain(_a) { diff --git a/tests/baselines/reference/objectSpread.js b/tests/baselines/reference/objectSpread.js index 4305e17ab310f..dc49d1f40ffea 100644 --- a/tests/baselines/reference/objectSpread.js +++ b/tests/baselines/reference/objectSpread.js @@ -87,6 +87,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 9946b313f52f3..0b2fce46b0dba 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -21,6 +21,7 @@ let addAfter: { a: number, b: string, c: boolean } = >c : Symbol(c, Decl(objectSpread.ts, 4, 37)) { ...o, c: false } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >c : Symbol(c, Decl(objectSpread.ts, 5, 11)) let addBefore: { a: number, b: string, c: boolean } = @@ -31,6 +32,7 @@ let addBefore: { a: number, b: string, c: boolean } = { c: false, ...o } >c : Symbol(c, Decl(objectSpread.ts, 7, 5)) +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) // Note: ignore still changes the order that properties are printed let ignore: { a: number, b: string } = @@ -40,6 +42,7 @@ let ignore: { a: number, b: string } = { b: 'ignored', ...o } >b : Symbol(b, Decl(objectSpread.ts, 10, 5)) +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) let override: { a: number, b: string } = >override : Symbol(override, Decl(objectSpread.ts, 11, 3)) @@ -47,6 +50,7 @@ let override: { a: number, b: string } = >b : Symbol(b, Decl(objectSpread.ts, 11, 26)) { ...o, b: 'override' } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >b : Symbol(b, Decl(objectSpread.ts, 12, 11)) let nested: { a: number, b: boolean, c: string } = @@ -68,6 +72,9 @@ let combined: { a: number, b: string, c: boolean } = >c : Symbol(c, Decl(objectSpread.ts, 15, 37)) { ...o, ...o2 } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) +>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3)) + let combinedBefore: { a: number, b: string, c: boolean } = >combinedBefore : Symbol(combinedBefore, Decl(objectSpread.ts, 17, 3)) >a : Symbol(a, Decl(objectSpread.ts, 17, 21)) @@ -76,6 +83,8 @@ let combinedBefore: { a: number, b: string, c: boolean } = { b: 'ok', ...o, ...o2 } >b : Symbol(b, Decl(objectSpread.ts, 18, 5)) +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) +>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3)) let combinedMid: { a: number, b: string, c: boolean } = >combinedMid : Symbol(combinedMid, Decl(objectSpread.ts, 19, 3)) @@ -84,7 +93,9 @@ let combinedMid: { a: number, b: string, c: boolean } = >c : Symbol(c, Decl(objectSpread.ts, 19, 40)) { ...o, b: 'ok', ...o2 } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >b : Symbol(b, Decl(objectSpread.ts, 20, 11)) +>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3)) let combinedAfter: { a: number, b: string, c: boolean } = >combinedAfter : Symbol(combinedAfter, Decl(objectSpread.ts, 21, 3)) @@ -93,6 +104,8 @@ let combinedAfter: { a: number, b: string, c: boolean } = >c : Symbol(c, Decl(objectSpread.ts, 21, 42)) { ...o, ...o2, b: 'ok' } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) +>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3)) >b : Symbol(b, Decl(objectSpread.ts, 22, 18)) let combinedNested: { a: number, b: boolean, c: string, d: string } = @@ -130,6 +143,7 @@ let propertyNested: { a: { a: number, b: string } } = { a: { ... o } } >a : Symbol(a, Decl(objectSpread.ts, 28, 5)) +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) // accessors don't copy the descriptor // (which means that readonly getters become read/write properties) @@ -143,6 +157,7 @@ let getter: { a: number, c: number } = >c : Symbol(c, Decl(objectSpread.ts, 32, 24)) { ...op, c: 7 } +>op : Symbol(op, Decl(objectSpread.ts, 31, 3)) >c : Symbol(c, Decl(objectSpread.ts, 33, 12)) getter.a = 12; @@ -160,6 +175,7 @@ let anything: any; let spreadAny = { ...anything }; >spreadAny : Symbol(spreadAny, Decl(objectSpread.ts, 41, 3)) +>anything : Symbol(anything, Decl(objectSpread.ts, 40, 3)) // methods are not enumerable class C { p = 1; m() { } } @@ -175,12 +191,14 @@ let c: C = new C() let spreadC: { p: number } = { ...c } >spreadC : Symbol(spreadC, Decl(objectSpread.ts, 46, 3)) >p : Symbol(p, Decl(objectSpread.ts, 46, 14)) +>c : Symbol(c, Decl(objectSpread.ts, 45, 3)) // own methods are enumerable let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } }; >cplus : Symbol(cplus, Decl(objectSpread.ts, 49, 3)) >p : Symbol(p, Decl(objectSpread.ts, 49, 12)) >plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) +>c : Symbol(c, Decl(objectSpread.ts, 45, 3)) >plus : Symbol(plus, Decl(objectSpread.ts, 49, 48)) >this : Symbol(__object, Decl(objectSpread.ts, 41, 15)) @@ -196,6 +214,7 @@ let changeTypeAfter: { a: string, b: string } = >b : Symbol(b, Decl(objectSpread.ts, 53, 33)) { ...o, a: 'wrong type?' } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >a : Symbol(a, Decl(objectSpread.ts, 54, 11)) let changeTypeBefore: { a: number, b: string } = @@ -205,6 +224,7 @@ let changeTypeBefore: { a: number, b: string } = { a: 'wrong type?', ...o }; >a : Symbol(a, Decl(objectSpread.ts, 56, 5)) +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) let changeTypeBoth: { a: string, b: number } = >changeTypeBoth : Symbol(changeTypeBoth, Decl(objectSpread.ts, 57, 3)) @@ -212,6 +232,8 @@ let changeTypeBoth: { a: string, b: number } = >b : Symbol(b, Decl(objectSpread.ts, 57, 32)) { ...o, ...swap }; +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) +>swap : Symbol(swap, Decl(objectSpread.ts, 2, 3)) // optional let definiteBoolean: { sn: boolean }; @@ -233,14 +255,23 @@ let optionalNumber: { sn?: number }; let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; >optionalUnionStops : Symbol(optionalUnionStops, Decl(objectSpread.ts, 65, 3)) >sn : Symbol(sn, Decl(objectSpread.ts, 65, 25)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 61, 3)) +>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 62, 3)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 64, 3)) let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; >optionalUnionDuplicates : Symbol(optionalUnionDuplicates, Decl(objectSpread.ts, 66, 3)) >sn : Symbol(sn, Decl(objectSpread.ts, 66, 30)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 61, 3)) +>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 62, 3)) +>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 63, 3)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 64, 3)) let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; >allOptional : Symbol(allOptional, Decl(objectSpread.ts, 67, 3)) >sn : Symbol(sn, Decl(objectSpread.ts, 67, 18)) +>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 63, 3)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 64, 3)) // computed property let computedFirst: { a: number, b: string, "before everything": number } = @@ -250,6 +281,7 @@ let computedFirst: { a: number, b: string, "before everything": number } = { ['before everything']: 12, ...o, b: 'yes' } >'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 71, 5)) +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >b : Symbol(b, Decl(objectSpread.ts, 71, 38)) let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = @@ -259,8 +291,10 @@ let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number >c : Symbol(c, Decl(objectSpread.ts, 72, 43)) { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >'in the middle' : Symbol(['in the middle'], Decl(objectSpread.ts, 73, 11)) >b : Symbol(b, Decl(objectSpread.ts, 73, 34)) +>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3)) let computedAfter: { a: number, b: string, "at the end": number } = >computedAfter : Symbol(computedAfter, Decl(objectSpread.ts, 74, 3)) @@ -268,6 +302,7 @@ let computedAfter: { a: number, b: string, "at the end": number } = >b : Symbol(b, Decl(objectSpread.ts, 74, 31)) { ...o, b: 'yeah', ['at the end']: 14 } +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >b : Symbol(b, Decl(objectSpread.ts, 75, 11)) >'at the end' : Symbol(['at the end'], Decl(objectSpread.ts, 75, 22)) @@ -279,6 +314,7 @@ let shortCutted: { a: number, b: string } = { ...o, a } >shortCutted : Symbol(shortCutted, Decl(objectSpread.ts, 78, 3)) >a : Symbol(a, Decl(objectSpread.ts, 78, 18)) >b : Symbol(b, Decl(objectSpread.ts, 78, 29)) +>o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >a : Symbol(a, Decl(objectSpread.ts, 78, 51)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index a1c70720d1296..a571bd0bb6330 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -32,7 +32,7 @@ let addAfter: { a: number, b: string, c: boolean } = { ...o, c: false } >{ ...o, c: false } : { c: false; a: number; b: string; } ->o : any +>o : { a: number; b: string; } >c : boolean >false : false @@ -46,7 +46,7 @@ let addBefore: { a: number, b: string, c: boolean } = >{ c: false, ...o } : { a: number; b: string; c: false; } >c : boolean >false : false ->o : any +>o : { a: number; b: string; } // Note: ignore still changes the order that properties are printed let ignore: { a: number, b: string } = @@ -58,7 +58,7 @@ let ignore: { a: number, b: string } = >{ b: 'ignored', ...o } : { a: number; b: string; } >b : string >'ignored' : "ignored" ->o : any +>o : { a: number; b: string; } let override: { a: number, b: string } = >override : { a: number; b: string; } @@ -67,7 +67,7 @@ let override: { a: number, b: string } = { ...o, b: 'override' } >{ ...o, b: 'override' } : { b: string; a: number; } ->o : any +>o : { a: number; b: string; } >b : string >'override' : "override" @@ -98,8 +98,8 @@ let combined: { a: number, b: string, c: boolean } = { ...o, ...o2 } >{ ...o, ...o2 } : { b: string; c: boolean; a: number; } ->o : any ->o2 : any +>o : { a: number; b: string; } +>o2 : { b: string; c: boolean; } let combinedBefore: { a: number, b: string, c: boolean } = >combinedBefore : { a: number; b: string; c: boolean; } @@ -111,8 +111,8 @@ let combinedBefore: { a: number, b: string, c: boolean } = >{ b: 'ok', ...o, ...o2 } : { b: string; c: boolean; a: number; } >b : string >'ok' : "ok" ->o : any ->o2 : any +>o : { a: number; b: string; } +>o2 : { b: string; c: boolean; } let combinedMid: { a: number, b: string, c: boolean } = >combinedMid : { a: number; b: string; c: boolean; } @@ -122,10 +122,10 @@ let combinedMid: { a: number, b: string, c: boolean } = { ...o, b: 'ok', ...o2 } >{ ...o, b: 'ok', ...o2 } : { b: string; c: boolean; a: number; } ->o : any +>o : { a: number; b: string; } >b : string >'ok' : "ok" ->o2 : any +>o2 : { b: string; c: boolean; } let combinedAfter: { a: number, b: string, c: boolean } = >combinedAfter : { a: number; b: string; c: boolean; } @@ -135,8 +135,8 @@ let combinedAfter: { a: number, b: string, c: boolean } = { ...o, ...o2, b: 'ok' } >{ ...o, ...o2, b: 'ok' } : { b: string; c: boolean; a: number; } ->o : any ->o2 : any +>o : { a: number; b: string; } +>o2 : { b: string; c: boolean; } >b : string >'ok' : "ok" @@ -195,7 +195,7 @@ let propertyNested: { a: { a: number, b: string } } = >{ a: { ... o } } : { a: { a: number; b: string; }; } >a : { a: number; b: string; } >{ ... o } : { a: number; b: string; } ->o : any +>o : { a: number; b: string; } // accessors don't copy the descriptor // (which means that readonly getters become read/write properties) @@ -212,7 +212,7 @@ let getter: { a: number, c: number } = { ...op, c: 7 } >{ ...op, c: 7 } : { c: number; readonly a: number; } ->op : any +>op : { readonly a: number; } >c : number >7 : 7 @@ -256,7 +256,7 @@ let spreadC: { p: number } = { ...c } >spreadC : { p: number; } >p : number >{ ...c } : { p: number; } ->c : any +>c : C // own methods are enumerable let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } }; @@ -264,7 +264,7 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >p : number >plus : () => void >{ ...c, plus() { return this.p + 1; } } : { plus(): any; p: number; } ->c : any +>c : C >plus : () => any >this.p + 1 : any >this.p : any @@ -286,7 +286,7 @@ let changeTypeAfter: { a: string, b: string } = { ...o, a: 'wrong type?' } >{ ...o, a: 'wrong type?' } : { a: string; b: string; } ->o : any +>o : { a: number; b: string; } >a : string >'wrong type?' : "wrong type?" @@ -299,7 +299,7 @@ let changeTypeBefore: { a: number, b: string } = >{ a: 'wrong type?', ...o } : { a: number; b: string; } >a : string >'wrong type?' : "wrong type?" ->o : any +>o : { a: number; b: string; } let changeTypeBoth: { a: string, b: number } = >changeTypeBoth : { a: string; b: number; } @@ -308,8 +308,8 @@ let changeTypeBoth: { a: string, b: number } = { ...o, ...swap }; >{ ...o, ...swap } : { a: string; b: number; } ->o : any ->swap : any +>o : { a: number; b: string; } +>swap : { a: string; b: number; } // optional let definiteBoolean: { sn: boolean }; @@ -332,25 +332,25 @@ let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean >optionalUnionStops : { sn: string | number | boolean; } >sn : string | number | boolean >{ ...definiteBoolean, ...definiteString, ...optionalNumber } : { sn: string | number; } ->definiteBoolean : any ->definiteString : any ->optionalNumber : any +>definiteBoolean : { sn: boolean; } +>definiteString : { sn: string; } +>optionalNumber : { sn?: number; } let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; >optionalUnionDuplicates : { sn: string | number; } >sn : string | number >{ ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber } : { sn: string | number; } ->definiteBoolean : any ->definiteString : any ->optionalString : any ->optionalNumber : any +>definiteBoolean : { sn: boolean; } +>definiteString : { sn: string; } +>optionalString : { sn?: string; } +>optionalNumber : { sn?: number; } let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; >allOptional : { sn?: string | number; } >sn : string | number >{ ...optionalString, ...optionalNumber } : { sn?: string | number; } ->optionalString : any ->optionalNumber : any +>optionalString : { sn?: string; } +>optionalNumber : { sn?: number; } // computed property let computedFirst: { a: number, b: string, "before everything": number } = @@ -362,7 +362,7 @@ let computedFirst: { a: number, b: string, "before everything": number } = >{ ['before everything']: 12, ...o, b: 'yes' } : { b: string; a: number; ['before everything']: number; } >'before everything' : "before everything" >12 : 12 ->o : any +>o : { a: number; b: string; } >b : string >'yes' : "yes" @@ -374,12 +374,12 @@ let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } >{ ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } : { b: string; c: boolean; ['in the middle']: number; a: number; } ->o : any +>o : { a: number; b: string; } >'in the middle' : "in the middle" >13 : 13 >b : string >'maybe?' : "maybe?" ->o2 : any +>o2 : { b: string; c: boolean; } let computedAfter: { a: number, b: string, "at the end": number } = >computedAfter : { a: number; b: string; "at the end": number; } @@ -388,7 +388,7 @@ let computedAfter: { a: number, b: string, "at the end": number } = { ...o, b: 'yeah', ['at the end']: 14 } >{ ...o, b: 'yeah', ['at the end']: 14 } : { b: string; ['at the end']: number; a: number; } ->o : any +>o : { a: number; b: string; } >b : string >'yeah' : "yeah" >'at the end' : "at the end" @@ -404,7 +404,7 @@ let shortCutted: { a: number, b: string } = { ...o, a } >a : number >b : string >{ ...o, a } : { a: number; b: string; } ->o : any +>o : { a: number; b: string; } >a : number diff --git a/tests/baselines/reference/objectSpreadComputedProperty.js b/tests/baselines/reference/objectSpreadComputedProperty.js new file mode 100644 index 0000000000000..6f27e696ae7f9 --- /dev/null +++ b/tests/baselines/reference/objectSpreadComputedProperty.js @@ -0,0 +1,34 @@ +//// [objectSpreadComputedProperty.ts] +// fixes #12200 +function f() { + let n: number = 12; + let m: number = 13; + let a: any = null; + const o1 = { ...{}, [n]: n }; + const o2 = { ...{}, [a]: n }; + const o3 = { [a]: n, ...{}, [n]: n, ...{}, [m]: m }; +} + + +//// [objectSpreadComputedProperty.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]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; + } + return t; +}; +// fixes #12200 +function f() { + var n = 12; + var m = 13; + var a = null; + var o1 = __assign({}, (_a = {}, _a[n] = n, _a)); + var o2 = __assign({}, (_b = {}, _b[a] = n, _b)); + var o3 = __assign((_c = {}, _c[a] = n, _c), {}, (_d = {}, _d[n] = n, _d), {}, (_e = {}, _e[m] = m, _e)); + var _a, _b, _c, _d, _e; +} diff --git a/tests/baselines/reference/objectSpreadComputedProperty.symbols b/tests/baselines/reference/objectSpreadComputedProperty.symbols new file mode 100644 index 0000000000000..57a0db0962bfb --- /dev/null +++ b/tests/baselines/reference/objectSpreadComputedProperty.symbols @@ -0,0 +1,34 @@ +=== tests/cases/conformance/types/spread/objectSpreadComputedProperty.ts === +// fixes #12200 +function f() { +>f : Symbol(f, Decl(objectSpreadComputedProperty.ts, 0, 0)) + + let n: number = 12; +>n : Symbol(n, Decl(objectSpreadComputedProperty.ts, 2, 7)) + + let m: number = 13; +>m : Symbol(m, Decl(objectSpreadComputedProperty.ts, 3, 7)) + + let a: any = null; +>a : Symbol(a, Decl(objectSpreadComputedProperty.ts, 4, 7)) + + const o1 = { ...{}, [n]: n }; +>o1 : Symbol(o1, Decl(objectSpreadComputedProperty.ts, 5, 9)) +>n : Symbol(n, Decl(objectSpreadComputedProperty.ts, 2, 7)) +>n : Symbol(n, Decl(objectSpreadComputedProperty.ts, 2, 7)) + + const o2 = { ...{}, [a]: n }; +>o2 : Symbol(o2, Decl(objectSpreadComputedProperty.ts, 6, 9)) +>a : Symbol(a, Decl(objectSpreadComputedProperty.ts, 4, 7)) +>n : Symbol(n, Decl(objectSpreadComputedProperty.ts, 2, 7)) + + const o3 = { [a]: n, ...{}, [n]: n, ...{}, [m]: m }; +>o3 : Symbol(o3, Decl(objectSpreadComputedProperty.ts, 7, 9)) +>a : Symbol(a, Decl(objectSpreadComputedProperty.ts, 4, 7)) +>n : Symbol(n, Decl(objectSpreadComputedProperty.ts, 2, 7)) +>n : Symbol(n, Decl(objectSpreadComputedProperty.ts, 2, 7)) +>n : Symbol(n, Decl(objectSpreadComputedProperty.ts, 2, 7)) +>m : Symbol(m, Decl(objectSpreadComputedProperty.ts, 3, 7)) +>m : Symbol(m, Decl(objectSpreadComputedProperty.ts, 3, 7)) +} + diff --git a/tests/baselines/reference/objectSpreadComputedProperty.types b/tests/baselines/reference/objectSpreadComputedProperty.types new file mode 100644 index 0000000000000..287936d43544f --- /dev/null +++ b/tests/baselines/reference/objectSpreadComputedProperty.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/types/spread/objectSpreadComputedProperty.ts === +// fixes #12200 +function f() { +>f : () => void + + let n: number = 12; +>n : number +>12 : 12 + + let m: number = 13; +>m : number +>13 : 13 + + let a: any = null; +>a : any +>null : null + + const o1 = { ...{}, [n]: n }; +>o1 : {} +>{ ...{}, [n]: n } : {} +>{} : {} +>n : number +>n : number + + const o2 = { ...{}, [a]: n }; +>o2 : {} +>{ ...{}, [a]: n } : {} +>{} : {} +>a : any +>n : number + + const o3 = { [a]: n, ...{}, [n]: n, ...{}, [m]: m }; +>o3 : {} +>{ [a]: n, ...{}, [n]: n, ...{}, [m]: m } : {} +>a : any +>n : number +>{} : {} +>n : number +>n : number +>{} : {} +>m : number +>m : number +} + diff --git a/tests/baselines/reference/objectSpreadIndexSignature.js b/tests/baselines/reference/objectSpreadIndexSignature.js index 22e92e6a844bf..ffe88a89c9a36 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.js +++ b/tests/baselines/reference/objectSpreadIndexSignature.js @@ -23,6 +23,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/objectSpreadIndexSignature.symbols b/tests/baselines/reference/objectSpreadIndexSignature.symbols index c51e7f4532f98..cd64b15719699 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.symbols +++ b/tests/baselines/reference/objectSpreadIndexSignature.symbols @@ -27,6 +27,7 @@ let indexed2: Indexed2; let i = { ...indexed, b: 11 }; >i : Symbol(i, Decl(objectSpreadIndexSignature.ts, 10, 3)) +>indexed : Symbol(indexed, Decl(objectSpreadIndexSignature.ts, 8, 3)) >b : Symbol(b, Decl(objectSpreadIndexSignature.ts, 10, 21)) // only indexed has indexer, so i[101]: any @@ -35,6 +36,8 @@ i[101]; let ii = { ...indexed, ...indexed2 }; >ii : Symbol(ii, Decl(objectSpreadIndexSignature.ts, 13, 3)) +>indexed : Symbol(indexed, Decl(objectSpreadIndexSignature.ts, 8, 3)) +>indexed2 : Symbol(indexed2, Decl(objectSpreadIndexSignature.ts, 9, 3)) // both have indexer, so i[1001]: number | boolean ii[1001]; diff --git a/tests/baselines/reference/objectSpreadIndexSignature.types b/tests/baselines/reference/objectSpreadIndexSignature.types index 79a515e73742d..5eebc2ffa02b7 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.types +++ b/tests/baselines/reference/objectSpreadIndexSignature.types @@ -28,7 +28,7 @@ let indexed2: Indexed2; let i = { ...indexed, b: 11 }; >i : { b: number; a: number; } >{ ...indexed, b: 11 } : { b: number; a: number; } ->indexed : any +>indexed : Indexed >b : number >11 : 11 @@ -41,8 +41,8 @@ i[101]; let ii = { ...indexed, ...indexed2 }; >ii : { [x: string]: number | boolean; c: boolean; a: number; } >{ ...indexed, ...indexed2 } : { [x: string]: number | boolean; c: boolean; a: number; } ->indexed : any ->indexed2 : any +>indexed : Indexed +>indexed2 : Indexed2 // both have indexer, so i[1001]: number | boolean ii[1001]; diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index 6287f4559a79b..472a0857169a3 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -77,6 +77,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/objectSpreadNegativeParse.js b/tests/baselines/reference/objectSpreadNegativeParse.js index 297c56c3e62ae..4076ab1c3a015 100644 --- a/tests/baselines/reference/objectSpreadNegativeParse.js +++ b/tests/baselines/reference/objectSpreadNegativeParse.js @@ -11,6 +11,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/objectSpreadNoTransform.symbols b/tests/baselines/reference/objectSpreadNoTransform.symbols index d7dac11a53041..78423330dbb14 100644 --- a/tests/baselines/reference/objectSpreadNoTransform.symbols +++ b/tests/baselines/reference/objectSpreadNoTransform.symbols @@ -7,6 +7,7 @@ const y = { a: 'yes', b: 'no' }; const o = { x: 1, ...y }; >o : Symbol(o, Decl(objectSpreadNoTransform.ts, 1, 5)) >x : Symbol(x, Decl(objectSpreadNoTransform.ts, 1, 11)) +>y : Symbol(y, Decl(objectSpreadNoTransform.ts, 0, 5)) var b; >b : Symbol(b, Decl(objectSpreadNoTransform.ts, 2, 3)) @@ -16,5 +17,6 @@ var rest; ({ b, ...rest } = o); >b : Symbol(b, Decl(objectSpreadNoTransform.ts, 4, 2)) +>rest : Symbol(rest, Decl(objectSpreadNoTransform.ts, 3, 3)) >o : Symbol(o, Decl(objectSpreadNoTransform.ts, 1, 5)) diff --git a/tests/baselines/reference/objectSpreadNoTransform.types b/tests/baselines/reference/objectSpreadNoTransform.types index 0a6c867e8fed4..ae89a3a7993e3 100644 --- a/tests/baselines/reference/objectSpreadNoTransform.types +++ b/tests/baselines/reference/objectSpreadNoTransform.types @@ -12,7 +12,7 @@ const o = { x: 1, ...y }; >{ x: 1, ...y } : { a: string; b: string; x: number; } >x : number >1 : 1 ->y : any +>y : { a: string; b: string; } var b; >b : any @@ -25,6 +25,6 @@ var rest; >{ b, ...rest } = o : { a: string; b: string; x: number; } >{ b, ...rest } : any >b : any ->rest : any +>rest : undefined >o : { a: string; b: string; x: number; } diff --git a/tests/baselines/reference/objectSpreadStrictNull.js b/tests/baselines/reference/objectSpreadStrictNull.js index 84604d728cdfc..fc0d4a80564a3 100644 --- a/tests/baselines/reference/objectSpreadStrictNull.js +++ b/tests/baselines/reference/objectSpreadStrictNull.js @@ -27,6 +27,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/objectSpreadStrictNull.symbols b/tests/baselines/reference/objectSpreadStrictNull.symbols index 85def473ce492..2586d4ddbd318 100644 --- a/tests/baselines/reference/objectSpreadStrictNull.symbols +++ b/tests/baselines/reference/objectSpreadStrictNull.symbols @@ -31,30 +31,51 @@ function f( let optionalUnionStops: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; >optionalUnionStops : Symbol(optionalUnionStops, Decl(objectSpreadStrictNull.ts, 9, 7)) >sn : Symbol(sn, Decl(objectSpreadStrictNull.ts, 9, 29)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpreadStrictNull.ts, 1, 11)) +>definiteString : Symbol(definiteString, Decl(objectSpreadStrictNull.ts, 2, 37)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpreadStrictNull.ts, 4, 36)) let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; >optionalUnionDuplicates : Symbol(optionalUnionDuplicates, Decl(objectSpreadStrictNull.ts, 10, 7)) >sn : Symbol(sn, Decl(objectSpreadStrictNull.ts, 10, 34)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpreadStrictNull.ts, 1, 11)) +>definiteString : Symbol(definiteString, Decl(objectSpreadStrictNull.ts, 2, 37)) +>optionalString : Symbol(optionalString, Decl(objectSpreadStrictNull.ts, 3, 35)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpreadStrictNull.ts, 4, 36)) let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; >allOptional : Symbol(allOptional, Decl(objectSpreadStrictNull.ts, 11, 7)) >sn : Symbol(sn, Decl(objectSpreadStrictNull.ts, 11, 22)) +>optionalString : Symbol(optionalString, Decl(objectSpreadStrictNull.ts, 3, 35)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpreadStrictNull.ts, 4, 36)) // undefined let undefinedUnionStops: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...undefinedNumber }; >undefinedUnionStops : Symbol(undefinedUnionStops, Decl(objectSpreadStrictNull.ts, 14, 7)) >sn : Symbol(sn, Decl(objectSpreadStrictNull.ts, 14, 30)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpreadStrictNull.ts, 1, 11)) +>definiteString : Symbol(definiteString, Decl(objectSpreadStrictNull.ts, 2, 37)) +>undefinedNumber : Symbol(undefinedNumber, Decl(objectSpreadStrictNull.ts, 6, 48)) let undefinedUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...undefinedString, ...undefinedNumber }; >undefinedUnionDuplicates : Symbol(undefinedUnionDuplicates, Decl(objectSpreadStrictNull.ts, 15, 7)) >sn : Symbol(sn, Decl(objectSpreadStrictNull.ts, 15, 35)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpreadStrictNull.ts, 1, 11)) +>definiteString : Symbol(definiteString, Decl(objectSpreadStrictNull.ts, 2, 37)) +>undefinedString : Symbol(undefinedString, Decl(objectSpreadStrictNull.ts, 5, 36)) +>undefinedNumber : Symbol(undefinedNumber, Decl(objectSpreadStrictNull.ts, 6, 48)) let allUndefined: { sn: string | number | undefined } = { ...undefinedString, ...undefinedNumber }; >allUndefined : Symbol(allUndefined, Decl(objectSpreadStrictNull.ts, 16, 7)) >sn : Symbol(sn, Decl(objectSpreadStrictNull.ts, 16, 23)) +>undefinedString : Symbol(undefinedString, Decl(objectSpreadStrictNull.ts, 5, 36)) +>undefinedNumber : Symbol(undefinedNumber, Decl(objectSpreadStrictNull.ts, 6, 48)) let undefinedWithOptionalContinues: { sn: string | number | boolean } = { ...definiteBoolean, ...undefinedString, ...optionalNumber }; >undefinedWithOptionalContinues : Symbol(undefinedWithOptionalContinues, Decl(objectSpreadStrictNull.ts, 18, 7)) >sn : Symbol(sn, Decl(objectSpreadStrictNull.ts, 18, 41)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpreadStrictNull.ts, 1, 11)) +>undefinedString : Symbol(undefinedString, Decl(objectSpreadStrictNull.ts, 5, 36)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpreadStrictNull.ts, 4, 36)) } diff --git a/tests/baselines/reference/objectSpreadStrictNull.types b/tests/baselines/reference/objectSpreadStrictNull.types index a91295b2bca78..c9ed742c6b626 100644 --- a/tests/baselines/reference/objectSpreadStrictNull.types +++ b/tests/baselines/reference/objectSpreadStrictNull.types @@ -32,57 +32,57 @@ function f( >optionalUnionStops : { sn: string | number; } >sn : string | number >{ ...definiteBoolean, ...definiteString, ...optionalNumber } : { sn: string | number; } ->definiteBoolean : any ->definiteString : any ->optionalNumber : any +>definiteBoolean : { sn: boolean; } +>definiteString : { sn: string; } +>optionalNumber : { sn?: number | undefined; } let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; >optionalUnionDuplicates : { sn: string | number; } >sn : string | number >{ ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber } : { sn: string | number; } ->definiteBoolean : any ->definiteString : any ->optionalString : any ->optionalNumber : any +>definiteBoolean : { sn: boolean; } +>definiteString : { sn: string; } +>optionalString : { sn?: string | undefined; } +>optionalNumber : { sn?: number | undefined; } let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; >allOptional : { sn?: string | number | undefined; } >sn : string | number | undefined >{ ...optionalString, ...optionalNumber } : { sn?: string | number | undefined; } ->optionalString : any ->optionalNumber : any +>optionalString : { sn?: string | undefined; } +>optionalNumber : { sn?: number | undefined; } // undefined let undefinedUnionStops: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...undefinedNumber }; >undefinedUnionStops : { sn: string | number; } >sn : string | number >{ ...definiteBoolean, ...definiteString, ...undefinedNumber } : { sn: string | number; } ->definiteBoolean : any ->definiteString : any ->undefinedNumber : any +>definiteBoolean : { sn: boolean; } +>definiteString : { sn: string; } +>undefinedNumber : { sn: number | undefined; } let undefinedUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...undefinedString, ...undefinedNumber }; >undefinedUnionDuplicates : { sn: string | number; } >sn : string | number >{ ...definiteBoolean, ...definiteString, ...undefinedString, ...undefinedNumber } : { sn: string | number; } ->definiteBoolean : any ->definiteString : any ->undefinedString : any ->undefinedNumber : any +>definiteBoolean : { sn: boolean; } +>definiteString : { sn: string; } +>undefinedString : { sn: string | undefined; } +>undefinedNumber : { sn: number | undefined; } let allUndefined: { sn: string | number | undefined } = { ...undefinedString, ...undefinedNumber }; >allUndefined : { sn: string | number | undefined; } >sn : string | number | undefined >{ ...undefinedString, ...undefinedNumber } : { sn: string | number | undefined; } ->undefinedString : any ->undefinedNumber : any +>undefinedString : { sn: string | undefined; } +>undefinedNumber : { sn: number | undefined; } let undefinedWithOptionalContinues: { sn: string | number | boolean } = { ...definiteBoolean, ...undefinedString, ...optionalNumber }; >undefinedWithOptionalContinues : { sn: string | number | boolean; } >sn : string | number | boolean >{ ...definiteBoolean, ...undefinedString, ...optionalNumber } : { sn: string | number | boolean; } ->definiteBoolean : any ->undefinedString : any ->optionalNumber : any +>definiteBoolean : { sn: boolean; } +>undefinedString : { sn: string | undefined; } +>optionalNumber : { sn?: number | undefined; } } diff --git a/tests/baselines/reference/reactNamespaceJSXEmit.js b/tests/baselines/reference/reactNamespaceJSXEmit.js index 3a21504bb80e7..48e514c2538ef 100644 --- a/tests/baselines/reference/reactNamespaceJSXEmit.js +++ b/tests/baselines/reference/reactNamespaceJSXEmit.js @@ -18,6 +18,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/tsxExternalModuleEmit2.js b/tests/baselines/reference/tsxExternalModuleEmit2.js index 6c01a48af7840..d3a6591cdaa77 100644 --- a/tests/baselines/reference/tsxExternalModuleEmit2.js +++ b/tests/baselines/reference/tsxExternalModuleEmit2.js @@ -24,6 +24,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/tsxReactEmit2.js b/tests/baselines/reference/tsxReactEmit2.js index 80e3215e2b6b1..4ddf442b53f41 100644 --- a/tests/baselines/reference/tsxReactEmit2.js +++ b/tests/baselines/reference/tsxReactEmit2.js @@ -21,6 +21,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/tsxReactEmit4.js b/tests/baselines/reference/tsxReactEmit4.js index 33c835d1ab22c..8ccc940880f5e 100644 --- a/tests/baselines/reference/tsxReactEmit4.js +++ b/tests/baselines/reference/tsxReactEmit4.js @@ -23,6 +23,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/tsxReactEmit5.js b/tests/baselines/reference/tsxReactEmit5.js index c3e58d0a0da54..6e4d43dd6768f 100644 --- a/tests/baselines/reference/tsxReactEmit5.js +++ b/tests/baselines/reference/tsxReactEmit5.js @@ -28,6 +28,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/baselines/reference/tsxReactEmit6.js b/tests/baselines/reference/tsxReactEmit6.js index 85aa8c123c99c..4c951354aa8a1 100644 --- a/tests/baselines/reference/tsxReactEmit6.js +++ b/tests/baselines/reference/tsxReactEmit6.js @@ -33,6 +33,9 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) + t[p[i]] = s[p[i]]; } return t; }; diff --git a/tests/cases/conformance/types/rest/objectRest.ts b/tests/cases/conformance/types/rest/objectRest.ts index f1a77b1c1299d..3f7be177c7bb1 100644 --- a/tests/cases/conformance/types/rest/objectRest.ts +++ b/tests/cases/conformance/types/rest/objectRest.ts @@ -1,5 +1,5 @@ // @target: es2015 -let o = { a: 1, b: 'no' } +var o = { a: 1, b: 'no' } var { ...clone } = o; var { a, ...justB } = o; var { a, b: renamed, ...empty } = o; @@ -31,3 +31,8 @@ class Removable { } var removable = new Removable(); var { removed, ...removableRest } = removable; + +let computed = 'b'; +let computed2 = 'a'; +var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; +({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); diff --git a/tests/cases/conformance/types/spread/objectSpreadComputedProperty.ts b/tests/cases/conformance/types/spread/objectSpreadComputedProperty.ts new file mode 100644 index 0000000000000..7e2182a2f1d88 --- /dev/null +++ b/tests/cases/conformance/types/spread/objectSpreadComputedProperty.ts @@ -0,0 +1,9 @@ +// fixes #12200 +function f() { + let n: number = 12; + let m: number = 13; + let a: any = null; + const o1 = { ...{}, [n]: n }; + const o2 = { ...{}, [a]: n }; + const o3 = { [a]: n, ...{}, [n]: n, ...{}, [m]: m }; +} diff --git a/tests/cases/fourslash/renameObjectSpreadAssignment.ts b/tests/cases/fourslash/renameObjectSpreadAssignment.ts new file mode 100644 index 0000000000000..9cf0b6ebf8156 --- /dev/null +++ b/tests/cases/fourslash/renameObjectSpreadAssignment.ts @@ -0,0 +1,20 @@ +/// + +////interface A1 { a: number }; +////interface A2 { a?: number }; +////let [|a1|]: A1; +////let [|a2|]: A2; +////let a12 = { ...[|a1|], ...[|a2|] }; +const ranges = test.ranges(); +verify.assertHasRanges(ranges); + +// rename a1 +goTo.position(ranges[0].start); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); +goTo.position(ranges[2].start); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[0], ranges[2]]); +// rename a2 +goTo.position(ranges[1].start); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[3]]); +goTo.position(ranges[3].start); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false, [ranges[1], ranges[3]]);