@@ -38,6 +38,8 @@ interface GenerateDtsResult {
3838 text : string ;
3939 mapping : CodeMapping ;
4040 linkedCodeMapping : LinkedCodeMapping ;
41+ /** Additional mappings used by ts-plugin (e.g. quoted string literal keys). */
42+ extraMappings ?: CodeMapping [ ] ;
4143}
4244
4345/**
@@ -113,7 +115,7 @@ function generateNamedExportsDts(
113115 localTokens : Token [ ] ,
114116 tokenImporters : TokenImporter [ ] ,
115117 options : GenerateDtsOptions ,
116- ) : { text : string ; mapping : CodeMapping ; linkedCodeMapping : LinkedCodeMapping } {
118+ ) : GenerateDtsResult {
117119 const mapping : CodeMapping = { sourceOffsets : [ ] , lengths : [ ] , generatedOffsets : [ ] } ;
118120 const linkedCodeMapping : LinkedCodeMapping = {
119121 sourceOffsets : [ ] ,
@@ -263,11 +265,10 @@ function generateNamedExportsDts(
263265}
264266
265267/** Generate a d.ts file with a default export. */
266- function generateDefaultExportDts (
267- localTokens : Token [ ] ,
268- tokenImporters : TokenImporter [ ] ,
269- ) : { text : string ; mapping : CodeMapping ; linkedCodeMapping : LinkedCodeMapping } {
268+ function generateDefaultExportDts ( localTokens : Token [ ] , tokenImporters : TokenImporter [ ] ) : GenerateDtsResult {
270269 const mapping : CodeMapping = { sourceOffsets : [ ] , lengths : [ ] , generatedOffsets : [ ] , generatedLengths : [ ] } ;
270+ //
271+ const quotedMapping : CodeMapping = { sourceOffsets : [ ] , lengths : [ ] , generatedOffsets : [ ] , generatedLengths : [ ] } ;
271272 const linkedCodeMapping : LinkedCodeMapping = {
272273 sourceOffsets : [ ] ,
273274 lengths : [ ] ,
@@ -326,16 +327,31 @@ function generateDefaultExportDts(
326327 */
327328
328329 text += ` ` ;
329- mapping . sourceOffsets . push ( token . loc . start . offset ) ;
330- mapping . generatedOffsets . push ( text . length ) ;
331- mapping . lengths . push ( token . name . length ) ;
332330 if ( isValidAsJSIdentifier ( token . name ) ) {
331+ mapping . sourceOffsets . push ( token . loc . start . offset ) ;
332+ mapping . lengths . push ( token . name . length ) ;
333+ mapping . generatedOffsets . push ( text . length ) ;
333334 mapping . generatedLengths ! . push ( token . name . length ) ;
334335 text += `${ token . name } : '' as readonly string,\n` ;
335336 } else {
336- // Include quotes in the mapping for invalid JS identifiers
337- mapping . generatedLengths ! . push ( token . name . length + 2 ) ;
338- text += `'${ token . name } ': '' as readonly string,\n` ;
337+ const quoteStart = text . length ;
338+ text += `'` ;
339+ const keyStart = text . length ;
340+ // Map unquoted range in the primary mapping.
341+ // This mapping is necessary when renaming.
342+ // When performing a rename, the textSpan does not include quotes,
343+ // but for "go to definition," the textSpan includes quotes, which necessitates a dual mapping.
344+ mapping . sourceOffsets . push ( token . loc . start . offset ) ;
345+ mapping . lengths . push ( token . name . length ) ;
346+ mapping . generatedOffsets . push ( keyStart ) ;
347+ mapping . generatedLengths ! . push ( token . name . length ) ;
348+ // Map quoted range separately to avoid overlapping ranges in a single mapping.
349+ // This mapping is necessary for features like "go to definition".
350+ quotedMapping . sourceOffsets . push ( token . loc . start . offset ) ;
351+ quotedMapping . lengths . push ( token . name . length ) ;
352+ quotedMapping . generatedOffsets . push ( quoteStart ) ;
353+ quotedMapping . generatedLengths ! . push ( token . name . length + 2 ) ;
354+ text += `${ token . name } ': '' as readonly string,\n` ;
339355 }
340356 }
341357 for ( const tokenImporter of tokenImporters ) {
@@ -438,6 +454,9 @@ function generateDefaultExportDts(
438454 }
439455 }
440456 text += `};\nexport default ${ STYLES_EXPORT_NAME } ;\n` ;
457+ if ( quotedMapping . sourceOffsets . length ) {
458+ return { text, mapping, linkedCodeMapping, extraMappings : [ quotedMapping ] } ;
459+ }
441460 return { text, mapping, linkedCodeMapping } ;
442461}
443462
0 commit comments