From 3edce5aa80ed664b07e998e323df60176ec582d1 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 29 Jun 2020 09:56:26 -0700 Subject: [PATCH] Fix type of computed name following spread --- src/compiler/checker.ts | 12 ++++++++---- ...ithIndexDoesNotAddUndefinedToLocalIndex.js | 19 +++++++++++++++++++ ...dexDoesNotAddUndefinedToLocalIndex.symbols | 11 +++++++++++ ...IndexDoesNotAddUndefinedToLocalIndex.types | 16 ++++++++++++++++ ...ithIndexDoesNotAddUndefinedToLocalIndex.ts | 3 +++ 5 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.js create mode 100644 tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.symbols create mode 100644 tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.types create mode 100644 tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aa0091f99523a..ba20f896c7e18 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23824,10 +23824,15 @@ namespace ts { return links.resolvedType; } + function isSymbolWithNumericName(symbol: Symbol) { + const firstDecl = symbol.declarations?.[0]; + return isNumericLiteralName(symbol.escapedName) || (firstDecl && isNamedDeclaration(firstDecl) && isNumericName(firstDecl.name)); + } + function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], kind: IndexKind): IndexInfo { const propTypes: Type[] = []; for (let i = offset; i < properties.length; i++) { - if (kind === IndexKind.String || isNumericName(node.properties[i].name!)) { + if (kind === IndexKind.String || isSymbolWithNumericName(properties[i])) { propTypes.push(getTypeOfSymbol(properties[i])); } } @@ -23880,8 +23885,7 @@ namespace ts { } let offset = 0; - for (let i = 0; i < node.properties.length; i++) { - const memberDecl = node.properties[i]; + for (const memberDecl of node.properties) { let member = getSymbolOfNode(memberDecl); const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically(memberDecl.name.expression) ? checkComputedPropertyName(memberDecl.name) : undefined; @@ -23965,7 +23969,7 @@ namespace ts { checkSpreadPropOverrides(type, allPropertiesTable, memberDecl); } spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext); - offset = i + 1; + offset = propertiesArray.length; continue; } else { diff --git a/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.js b/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.js new file mode 100644 index 0000000000000..570580f17e87a --- /dev/null +++ b/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.js @@ -0,0 +1,19 @@ +//// [spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts] +declare const m: { [k: string]: string }; +const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" }; + +//// [spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.js] +"use strict"; +var __assign = (this && this.__assign) || function () { + __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; + }; + return __assign.apply(this, arguments); +}; +var _a; +var x = __assign(__assign({}, m), (_a = {}, _a["a" + "b"] = "", _a)); diff --git a/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.symbols b/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.symbols new file mode 100644 index 0000000000000..d41f4c8fe0933 --- /dev/null +++ b/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts === +declare const m: { [k: string]: string }; +>m : Symbol(m, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 0, 13)) +>k : Symbol(k, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 0, 20)) + +const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" }; +>x : Symbol(x, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 1, 5)) +>k : Symbol(k, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 1, 12)) +>m : Symbol(m, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 0, 13)) +>["a" + "b"] : Symbol(["a" + "b"], Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 1, 42)) + diff --git a/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.types b/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.types new file mode 100644 index 0000000000000..9a76d8dfdaf52 --- /dev/null +++ b/tests/baselines/reference/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts === +declare const m: { [k: string]: string }; +>m : { [k: string]: string; } +>k : string + +const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" }; +>x : { [k: string]: string; } +>k : string +>{ ...m, ["a" + "b"]: "" } : { [x: string]: string; } +>m : { [k: string]: string; } +>["a" + "b"] : string +>"a" + "b" : string +>"a" : "a" +>"b" : "b" +>"" : "" + diff --git a/tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts b/tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts new file mode 100644 index 0000000000000..48cf12239caf7 --- /dev/null +++ b/tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts @@ -0,0 +1,3 @@ +// @strict: true +declare const m: { [k: string]: string }; +const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" }; \ No newline at end of file