@@ -1951,6 +1951,48 @@ func (b *nodeBuilderImpl) serializeReturnTypeForSignature(signature *Signature)
1951
1951
return returnTypeNode
1952
1952
}
1953
1953
1954
+ func (b * nodeBuilderImpl ) indexInfoToObjectComputedNamesOrSignatureDeclaration (indexInfo * IndexInfo , typeNode * ast.TypeNode ) []* ast.TypeElement {
1955
+ if len (indexInfo .components ) != 0 {
1956
+ // Index info is derived from object or class computed property names (plus explicit named members) - we can clone those instead of writing out the result computed index signature
1957
+ allComponentComputedNamesSerializable := b .ctx .enclosingDeclaration != nil && core .Every (indexInfo .components , func (c * ast.Node ) bool {
1958
+ return c .Name () != nil &&
1959
+ ast .IsComputedPropertyName (c .Name ()) &&
1960
+ ast .IsEntityNameExpression (c .Name ().AsComputedPropertyName ().Expression ) &&
1961
+ b .ch .GetEmitResolver ().isEntityNameVisible (c .Name ().AsComputedPropertyName ().Expression , b .ctx .enclosingDeclaration , false ).Accessibility == printer .SymbolAccessibilityAccessible
1962
+ })
1963
+ if allComponentComputedNamesSerializable {
1964
+ // Only use computed name serialization form if all components are visible and take the `a.b.c` form
1965
+ var newComponents []* ast.Node
1966
+ for _ , c := range indexInfo .components {
1967
+ // skip late bound props that contribute to the index signature - they'll be created by property creation anyway
1968
+ if ! b .ch .hasLateBindableName (c ) {
1969
+ newComponents = append (newComponents , c )
1970
+ }
1971
+ }
1972
+ result := make ([]* ast.TypeElement , 0 , len (newComponents ))
1973
+ for _ , c := range newComponents {
1974
+ // Still need to track visibility even if we've already checked it to paint references as used
1975
+ b .trackComputedName (c .Name ().AsComputedPropertyName ().Expression , b .ctx .enclosingDeclaration )
1976
+ var modifiers * ast.ModifierList
1977
+ if indexInfo .isReadonly {
1978
+ modifiers = b .f .NewModifierList ([]* ast.Node {b .f .NewModifier (ast .KindReadonlyKeyword )})
1979
+ }
1980
+ var questionToken * ast.Node
1981
+ if c .QuestionToken () != nil {
1982
+ questionToken = b .f .NewToken (ast .KindQuestionToken )
1983
+ }
1984
+ if typeNode == nil {
1985
+ typeNode = b .typeToTypeNode (b .ch .getTypeOfSymbol (c .Symbol ()))
1986
+ }
1987
+ propertySignature := b .f .NewPropertySignatureDeclaration (modifiers , c .Name (), questionToken , typeNode , nil )
1988
+ result = append (result , propertySignature )
1989
+ }
1990
+ return result
1991
+ }
1992
+ }
1993
+ return []* ast.TypeElement {b .indexInfoToIndexSignatureDeclarationHelper (indexInfo , typeNode )}
1994
+ }
1995
+
1954
1996
func (b * nodeBuilderImpl ) indexInfoToIndexSignatureDeclarationHelper (indexInfo * IndexInfo , typeNode * ast.TypeNode ) * ast.Node {
1955
1997
name := getNameFromIndexInfo (indexInfo )
1956
1998
indexerTypeNode := b .typeToTypeNode (indexInfo .keyType )
@@ -2083,9 +2125,15 @@ func (b *nodeBuilderImpl) shouldUsePlaceholderForProperty(propertySymbol *ast.Sy
2083
2125
func (b * nodeBuilderImpl ) trackComputedName (accessExpression * ast.Node , enclosingDeclaration * ast.Node ) {
2084
2126
// get symbol of the first identifier of the entityName
2085
2127
firstIdentifier := ast .GetFirstIdentifier (accessExpression )
2086
- name := b .ch .resolveName (firstIdentifier , firstIdentifier .Text (), ast .SymbolFlagsValue | ast .SymbolFlagsExportValue , nil /*nameNotFoundMessage*/ , true /*isUse*/ , false )
2128
+ name := b .ch .resolveName (enclosingDeclaration , firstIdentifier .Text (), ast .SymbolFlagsValue | ast .SymbolFlagsExportValue , nil /*nameNotFoundMessage*/ , true /*isUse*/ , false )
2087
2129
if name != nil {
2088
2130
b .ctx .tracker .TrackSymbol (name , enclosingDeclaration , ast .SymbolFlagsValue )
2131
+ } else {
2132
+ // Name does not resolve at target location, track symbol at dest location (should be inaccessible)
2133
+ fallback := b .ch .resolveName (firstIdentifier , firstIdentifier .Text (), ast .SymbolFlagsValue | ast .SymbolFlagsExportValue , nil /*nameNotFoundMessage*/ , true /*isUse*/ , false )
2134
+ if fallback != nil {
2135
+ b .ctx .tracker .TrackSymbol (fallback , enclosingDeclaration , ast .SymbolFlagsValue )
2136
+ }
2089
2137
}
2090
2138
}
2091
2139
@@ -2331,7 +2379,7 @@ func (b *nodeBuilderImpl) createTypeNodesFromResolvedType(resolvedType *Structur
2331
2379
typeElements = append (typeElements , b .signatureToSignatureDeclarationHelper (signature , ast .KindConstructSignature , nil ))
2332
2380
}
2333
2381
for _ , info := range resolvedType .indexInfos {
2334
- typeElements = append (typeElements , b .indexInfoToIndexSignatureDeclarationHelper (info , core .IfElse (resolvedType .objectFlags & ObjectFlagsReverseMapped != 0 , b .createElidedInformationPlaceholder (), nil )))
2382
+ typeElements = append (typeElements , b .indexInfoToObjectComputedNamesOrSignatureDeclaration (info , core .IfElse (resolvedType .objectFlags & ObjectFlagsReverseMapped != 0 , b .createElidedInformationPlaceholder (), nil ))... )
2335
2383
}
2336
2384
2337
2385
properties := resolvedType .properties
0 commit comments