@@ -25,10 +25,19 @@ import type { Plugin, RenderedChunk } from 'rolldown'
2525// export declare function x$1(xx: X$1): void
2626
2727type Dep = t . Expression & { replace ?: ( newNode : t . Node ) => void }
28+
29+ /**
30+ * A collection of type parameters grouped by parameter name
31+ */
32+ type GroupedTypeParams = Array < {
33+ name : string
34+ typeParams : t . TSTypeParameter [ ]
35+ } >
36+
2837interface SymbolInfo {
2938 decl : t . Declaration
3039 bindings : t . Identifier [ ]
31- params : t . TSTypeParameter [ ]
40+ params : GroupedTypeParams
3241 deps : Dep [ ]
3342}
3443
@@ -179,11 +188,7 @@ export function createFakeJsPlugin({
179188 decl . id = binding
180189 }
181190
182- const params : t . TSTypeParameter [ ] =
183- 'typeParameters' in decl &&
184- decl . typeParameters ?. type === 'TSTypeParameterDeclaration'
185- ? decl . typeParameters . params
186- : [ ]
191+ const params : GroupedTypeParams = collectParams ( decl )
187192
188193 const deps = collectDependencies ( decl , namespaceStmts )
189194
@@ -200,7 +205,7 @@ export function createFakeJsPlugin({
200205
201206 const symbolIdNode = t . numericLiteral ( symbolId )
202207 const depsNode = t . arrowFunctionExpression (
203- params . map ( ( param ) => t . identifier ( param . name ) ) ,
208+ params . map ( ( { name } ) => t . identifier ( name ) ) ,
204209 t . arrayExpression ( deps ) ,
205210 )
206211 const sideEffectNode =
@@ -312,10 +317,12 @@ export function createFakeJsPlugin({
312317 }
313318
314319 const transformedParams = depsFn . params as t . Identifier [ ]
315- for ( let i = 0 ; i < original . params . length ; i ++ ) {
316- const originalParam = original . params [ i ]
317- const transformedParam = transformedParams [ i ]
318- originalParam . name = transformedParam . name
320+
321+ for ( const [ i , transformedParam ] of transformedParams . entries ( ) ) {
322+ const transformedName = transformedParam . name
323+ for ( const originalTypeParam of original . params [ i ] . typeParams ) {
324+ originalTypeParam . name = transformedName
325+ }
319326 }
320327
321328 const transformedDeps = ( depsFn . body as t . ArrayExpression )
@@ -385,6 +392,42 @@ export function createFakeJsPlugin({
385392 return symbolMap . get ( symbolId ) !
386393 }
387394
395+ /**
396+ * Collects all TSTypeParameter nodes from the given node and groups them by
397+ * their name. One name can associate with one or more type parameters. These
398+ * names will be used as the parameter name in the generated JavaScript
399+ * dependency function.
400+ */
401+ function collectParams ( node : t . Node ) : GroupedTypeParams {
402+ const typeParams : t . TSTypeParameter [ ] = [ ]
403+ ; ( walk as any ) ( node , {
404+ leave ( node : t . Node ) {
405+ if (
406+ 'typeParameters' in node &&
407+ node . typeParameters ?. type === 'TSTypeParameterDeclaration'
408+ ) {
409+ typeParams . push ( ...node . typeParameters . params )
410+ }
411+ } ,
412+ } )
413+
414+ const paramMap = new Map < string , t . TSTypeParameter [ ] > ( )
415+ for ( const typeParam of typeParams ) {
416+ const name = typeParam . name
417+ const group = paramMap . get ( name )
418+ if ( group ) {
419+ group . push ( typeParam )
420+ } else {
421+ paramMap . set ( name , [ typeParam ] )
422+ }
423+ }
424+
425+ return Array . from ( paramMap . entries ( ) ) . map ( ( [ name , typeParams ] ) => ( {
426+ name,
427+ typeParams,
428+ } ) )
429+ }
430+
388431 function collectDependencies (
389432 node : t . Node ,
390433 namespaceStmts : NamespaceMap ,
0 commit comments