@@ -3891,6 +3891,12 @@ namespace ts {
3891
3891
return result || emptyArray;
3892
3892
}
3893
3893
3894
+ function getNamedOrIndexSignatureMembers(members: SymbolTable): Symbol[] {
3895
+ const result = getNamedMembers(members);
3896
+ const index = getIndexSymbolFromSymbolTable(members);
3897
+ return index ? concatenate(result, [index]) : result;
3898
+ }
3899
+
3894
3900
function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType {
3895
3901
const resolved = <ResolvedType>type;
3896
3902
resolved.members = members;
@@ -10764,6 +10770,7 @@ namespace ts {
10764
10770
// Combinations of function, class, enum and module
10765
10771
let members = emptySymbols;
10766
10772
let stringIndexInfo: IndexInfo | undefined;
10773
+ let numberIndexInfo: IndexInfo | undefined;
10767
10774
if (symbol.exports) {
10768
10775
members = getExportsOfSymbol(symbol);
10769
10776
if (symbol === globalThisSymbol) {
@@ -10776,20 +10783,32 @@ namespace ts {
10776
10783
members = varsOnly;
10777
10784
}
10778
10785
}
10786
+ let baseConstructorIndexInfo: IndexInfo | undefined;
10779
10787
setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined);
10780
10788
if (symbol.flags & SymbolFlags.Class) {
10781
10789
const classType = getDeclaredTypeOfClassOrInterface(symbol);
10782
10790
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
10783
10791
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) {
10784
- members = createSymbolTable(getNamedMembers (members));
10792
+ members = createSymbolTable(getNamedOrIndexSignatureMembers (members));
10785
10793
addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
10786
10794
}
10787
10795
else if (baseConstructorType === anyType) {
10788
- stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
10796
+ baseConstructorIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
10797
+ }
10798
+ }
10799
+
10800
+ const indexSymbol = getIndexSymbolFromSymbolTable(members);
10801
+ if (indexSymbol) {
10802
+ stringIndexInfo = getIndexInfoOfIndexSymbol(indexSymbol, IndexKind.String);
10803
+ numberIndexInfo = getIndexInfoOfIndexSymbol(indexSymbol, IndexKind.Number);
10804
+ }
10805
+ else {
10806
+ stringIndexInfo = baseConstructorIndexInfo;
10807
+ if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum ||
10808
+ some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike)))) {
10809
+ numberIndexInfo = enumNumberIndexInfo;
10789
10810
}
10790
10811
}
10791
- const numberIndexInfo = symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum ||
10792
- some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike))) ? enumNumberIndexInfo : undefined;
10793
10812
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
10794
10813
// We resolve the members before computing the signatures because a signature may use
10795
10814
// typeof with a qualified name expression that circularly references the type we are
@@ -10817,6 +10836,13 @@ namespace ts {
10817
10836
}
10818
10837
}
10819
10838
10839
+ function getIndexInfoOfIndexSymbol(indexSymbol: Symbol, indexKind: IndexKind) {
10840
+ const declaration = getIndexDeclarationOfIndexSymbol(indexSymbol, indexKind);
10841
+ if (!declaration) return undefined;
10842
+ return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType,
10843
+ hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration);
10844
+ }
10845
+
10820
10846
function resolveReverseMappedTypeMembers(type: ReverseMappedType) {
10821
10847
const indexInfo = getIndexInfoOfType(type.source, IndexKind.String);
10822
10848
const modifiers = getMappedTypeModifiers(type.mappedType);
@@ -12363,12 +12389,20 @@ namespace ts {
12363
12389
}
12364
12390
12365
12391
function getIndexSymbol(symbol: Symbol): Symbol | undefined {
12366
- return symbol.members!.get(InternalSymbolName.Index);
12392
+ return symbol.members ? getIndexSymbolFromSymbolTable(symbol.members) : undefined;
12393
+ }
12394
+
12395
+ function getIndexSymbolFromSymbolTable(symbolTable: SymbolTable): Symbol | undefined {
12396
+ return symbolTable.get(InternalSymbolName.Index);
12397
+ }
12398
+
12399
+ function getIndexDeclarationOfSymbol(symbol: Symbol | undefined, kind: IndexKind): IndexSignatureDeclaration | undefined {
12400
+ const indexSymbol = symbol && getIndexSymbol(symbol);
12401
+ return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind);
12367
12402
}
12368
12403
12369
- function getIndexDeclarationOfSymbol(symbol : Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined {
12404
+ function getIndexDeclarationOfIndexSymbol(indexSymbol : Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined {
12370
12405
const syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword;
12371
- const indexSymbol = getIndexSymbol(symbol);
12372
12406
if (indexSymbol?.declarations) {
12373
12407
for (const decl of indexSymbol.declarations) {
12374
12408
const node = cast(decl, isIndexSignatureDeclaration);
@@ -36723,6 +36757,7 @@ namespace ts {
36723
36757
36724
36758
if (produceDiagnostics) {
36725
36759
checkIndexConstraints(type);
36760
+ checkIndexConstraints(staticType);
36726
36761
checkTypeForDuplicateIndexSignatures(node);
36727
36762
checkPropertyInitialization(node);
36728
36763
}
@@ -40109,7 +40144,7 @@ namespace ts {
40109
40144
if (node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.MethodSignature) {
40110
40145
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_type_member, tokenToString(modifier.kind));
40111
40146
}
40112
- if (node.kind === SyntaxKind.IndexSignature) {
40147
+ if (node.kind === SyntaxKind.IndexSignature && (modifier.kind !== SyntaxKind.StaticKeyword || !isClassLike(node.parent)) ) {
40113
40148
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_index_signature, tokenToString(modifier.kind));
40114
40149
}
40115
40150
}
0 commit comments