Skip to content

Commit ff1f449

Browse files
authored
Fix type of computed name following spread (microsoft#39319)
1 parent 8b6a887 commit ff1f449

5 files changed

+57
-4
lines changed

src/compiler/checker.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -23836,10 +23836,15 @@ namespace ts {
2383623836
return links.resolvedType;
2383723837
}
2383823838

23839+
function isSymbolWithNumericName(symbol: Symbol) {
23840+
const firstDecl = symbol.declarations?.[0];
23841+
return isNumericLiteralName(symbol.escapedName) || (firstDecl && isNamedDeclaration(firstDecl) && isNumericName(firstDecl.name));
23842+
}
23843+
2383923844
function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], kind: IndexKind): IndexInfo {
2384023845
const propTypes: Type[] = [];
2384123846
for (let i = offset; i < properties.length; i++) {
23842-
if (kind === IndexKind.String || isNumericName(node.properties[i].name!)) {
23847+
if (kind === IndexKind.String || isSymbolWithNumericName(properties[i])) {
2384323848
propTypes.push(getTypeOfSymbol(properties[i]));
2384423849
}
2384523850
}
@@ -23892,8 +23897,7 @@ namespace ts {
2389223897
}
2389323898

2389423899
let offset = 0;
23895-
for (let i = 0; i < node.properties.length; i++) {
23896-
const memberDecl = node.properties[i];
23900+
for (const memberDecl of node.properties) {
2389723901
let member = getSymbolOfNode(memberDecl);
2389823902
const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically(memberDecl.name.expression) ?
2389923903
checkComputedPropertyName(memberDecl.name) : undefined;
@@ -23980,7 +23984,7 @@ namespace ts {
2398023984
checkSpreadPropOverrides(type, allPropertiesTable, memberDecl);
2398123985
}
2398223986
spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
23983-
offset = i + 1;
23987+
offset = propertiesArray.length;
2398423988
continue;
2398523989
}
2398623990
else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts]
2+
declare const m: { [k: string]: string };
3+
const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" };
4+
5+
//// [spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.js]
6+
"use strict";
7+
var __assign = (this && this.__assign) || function () {
8+
__assign = Object.assign || function(t) {
9+
for (var s, i = 1, n = arguments.length; i < n; i++) {
10+
s = arguments[i];
11+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
12+
t[p] = s[p];
13+
}
14+
return t;
15+
};
16+
return __assign.apply(this, arguments);
17+
};
18+
var _a;
19+
var x = __assign(__assign({}, m), (_a = {}, _a["a" + "b"] = "", _a));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts ===
2+
declare const m: { [k: string]: string };
3+
>m : Symbol(m, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 0, 13))
4+
>k : Symbol(k, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 0, 20))
5+
6+
const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" };
7+
>x : Symbol(x, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 1, 5))
8+
>k : Symbol(k, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 1, 12))
9+
>m : Symbol(m, Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 0, 13))
10+
>["a" + "b"] : Symbol(["a" + "b"], Decl(spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts, 1, 42))
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts ===
2+
declare const m: { [k: string]: string };
3+
>m : { [k: string]: string; }
4+
>k : string
5+
6+
const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" };
7+
>x : { [k: string]: string; }
8+
>k : string
9+
>{ ...m, ["a" + "b"]: "" } : { [x: string]: string; }
10+
>m : { [k: string]: string; }
11+
>["a" + "b"] : string
12+
>"a" + "b" : string
13+
>"a" : "a"
14+
>"b" : "b"
15+
>"" : ""
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// @strict: true
2+
declare const m: { [k: string]: string };
3+
const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" };

0 commit comments

Comments
 (0)