Skip to content

Commit 429b0d9

Browse files
committed
Union multiple spread index signatures
1 parent d6e414c commit 429b0d9

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

src/compiler/checker.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,6 +2321,8 @@ namespace ts {
23212321
printFollowingPunctuation = true;
23222322
}
23232323
}
2324+
// TODO: Only print if this is directly on the type -- not on the subtype somewhere.
2325+
// (This is not crucial, though, since the extra info *might* be nice.)
23242326
const resolved = resolveStructuredTypeMembers(type);
23252327
writeIndexSignature(resolved.stringIndexInfo, SyntaxKind.StringKeyword);
23262328
writeIndexSignature(resolved.numberIndexInfo, SyntaxKind.NumberKeyword);
@@ -4291,6 +4293,11 @@ namespace ts {
42914293
getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
42924294
}
42934295

4296+
function unionIndexInfos(info1: IndexInfo, info2: IndexInfo): IndexInfo {
4297+
return !info1 ? info2 : !info2 ? info1 : createIndexInfo(
4298+
getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
4299+
}
4300+
42944301
function resolveIntersectionTypeMembers(type: IntersectionType) {
42954302
// The members and properties collections are empty for intersection types. To get all properties of an
42964303
// intersection type use getPropertiesOfType (only the language service uses this).
@@ -4315,8 +4322,8 @@ namespace ts {
43154322
for (let i = type.types.length - 1; i > -1; i--) {
43164323
const t = type.types[i];
43174324
if (!t.isDeclaredProperty) {
4318-
stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String));
4319-
numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number));
4325+
stringIndexInfo = unionIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String));
4326+
numberIndexInfo = unionIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number));
43204327
}
43214328
}
43224329
setObjectTypeMembers(type, emptySymbols, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
@@ -16839,7 +16846,9 @@ namespace ts {
1683916846
// perform property check if property or indexer is declared in 'type'
1684016847
// this allows to rule out cases when both property and indexer are inherited from the base class
1684116848
let errorNode: Node;
16842-
if (prop.valueDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) {
16849+
if (prop.valueDeclaration.name.kind === SyntaxKind.ComputedPropertyName ||
16850+
prop.parent === containingType.symbol ||
16851+
containingType.flags & TypeFlags.Spread) {
1684316852
errorNode = prop.valueDeclaration;
1684416853
}
1684516854
else if (indexDeclaration) {

0 commit comments

Comments
 (0)