@@ -118,38 +118,46 @@ interface ResolvedElements {
118118export function resolveTypeElements (
119119 ctx : TypeResolveContext ,
120120 node : Node & MaybeWithScope & { _resolvedElements ?: ResolvedElements } ,
121- scope ?: TypeScope
121+ scope ?: TypeScope ,
122+ typeParameters ?: Record < string , Node >
122123) : ResolvedElements {
123124 if ( node . _resolvedElements ) {
124125 return node . _resolvedElements
125126 }
126127 return ( node . _resolvedElements = innerResolveTypeElements (
127128 ctx ,
128129 node ,
129- node . _ownerScope || scope || ctxToScope ( ctx )
130+ node . _ownerScope || scope || ctxToScope ( ctx ) ,
131+ typeParameters
130132 ) )
131133}
132134
133135function innerResolveTypeElements (
134136 ctx : TypeResolveContext ,
135137 node : Node ,
136- scope : TypeScope
138+ scope : TypeScope ,
139+ typeParameters ?: Record < string , Node >
137140) : ResolvedElements {
138141 switch ( node . type ) {
139142 case 'TSTypeLiteral' :
140- return typeElementsToMap ( ctx , node . members , scope )
143+ return typeElementsToMap ( ctx , node . members , scope , typeParameters )
141144 case 'TSInterfaceDeclaration' :
142- return resolveInterfaceMembers ( ctx , node , scope )
145+ return resolveInterfaceMembers ( ctx , node , scope , typeParameters )
143146 case 'TSTypeAliasDeclaration' :
144147 case 'TSParenthesizedType' :
145- return resolveTypeElements ( ctx , node . typeAnnotation , scope )
148+ return resolveTypeElements (
149+ ctx ,
150+ node . typeAnnotation ,
151+ scope ,
152+ typeParameters
153+ )
146154 case 'TSFunctionType' : {
147155 return { props : { } , calls : [ node ] }
148156 }
149157 case 'TSUnionType' :
150158 case 'TSIntersectionType' :
151159 return mergeElements (
152- node . types . map ( t => resolveTypeElements ( ctx , t , scope ) ) ,
160+ node . types . map ( t => resolveTypeElements ( ctx , t , scope , typeParameters ) ) ,
153161 node . type
154162 )
155163 case 'TSMappedType' :
@@ -171,20 +179,57 @@ function innerResolveTypeElements(
171179 scope . imports [ typeName ] ?. source === 'vue'
172180 ) {
173181 return resolveExtractPropTypes (
174- resolveTypeElements ( ctx , node . typeParameters . params [ 0 ] , scope ) ,
182+ resolveTypeElements (
183+ ctx ,
184+ node . typeParameters . params [ 0 ] ,
185+ scope ,
186+ typeParameters
187+ ) ,
175188 scope
176189 )
177190 }
178191 const resolved = resolveTypeReference ( ctx , node , scope )
179192 if ( resolved ) {
180- return resolveTypeElements ( ctx , resolved , resolved . _ownerScope )
193+ const typeParams : Record < string , Node > = Object . create ( null )
194+ if (
195+ ( resolved . type === 'TSTypeAliasDeclaration' ||
196+ resolved . type === 'TSInterfaceDeclaration' ) &&
197+ resolved . typeParameters &&
198+ node . typeParameters
199+ ) {
200+ resolved . typeParameters . params . forEach ( ( p , i ) => {
201+ let param = typeParameters && typeParameters [ p . name ]
202+ if ( ! param ) param = node . typeParameters ! . params [ i ]
203+ typeParams [ p . name ] = param
204+ } )
205+ }
206+ return resolveTypeElements (
207+ ctx ,
208+ resolved ,
209+ resolved . _ownerScope ,
210+ typeParams
211+ )
181212 } else {
182213 if ( typeof typeName === 'string' ) {
214+ if ( typeParameters && typeParameters [ typeName ] ) {
215+ return resolveTypeElements (
216+ ctx ,
217+ typeParameters [ typeName ] ,
218+ scope ,
219+ typeParameters
220+ )
221+ }
183222 if (
184223 // @ts -ignore
185224 SupportedBuiltinsSet . has ( typeName )
186225 ) {
187- return resolveBuiltin ( ctx , node , typeName as any , scope )
226+ return resolveBuiltin (
227+ ctx ,
228+ node ,
229+ typeName as any ,
230+ scope ,
231+ typeParameters
232+ )
188233 } else if ( typeName === 'ReturnType' && node . typeParameters ) {
189234 // limited support, only reference types
190235 const ret = resolveReturnType (
@@ -243,11 +288,17 @@ function innerResolveTypeElements(
243288function typeElementsToMap (
244289 ctx : TypeResolveContext ,
245290 elements : TSTypeElement [ ] ,
246- scope = ctxToScope ( ctx )
291+ scope = ctxToScope ( ctx ) ,
292+ typeParameters ?: Record < string , Node >
247293) : ResolvedElements {
248294 const res : ResolvedElements = { props : { } }
249295 for ( const e of elements ) {
250296 if ( e . type === 'TSPropertySignature' || e . type === 'TSMethodSignature' ) {
297+ // capture generic parameters on node's scope
298+ if ( typeParameters ) {
299+ scope = createChildScope ( scope )
300+ Object . assign ( scope . types , typeParameters )
301+ }
251302 ; ( e as MaybeWithScope ) . _ownerScope = scope
252303 const name = getId ( e . key )
253304 if ( name && ! e . computed ) {
@@ -323,9 +374,15 @@ function createProperty(
323374function resolveInterfaceMembers (
324375 ctx : TypeResolveContext ,
325376 node : TSInterfaceDeclaration & MaybeWithScope ,
326- scope : TypeScope
377+ scope : TypeScope ,
378+ typeParameters ?: Record < string , Node >
327379) : ResolvedElements {
328- const base = typeElementsToMap ( ctx , node . body . body , node . _ownerScope )
380+ const base = typeElementsToMap (
381+ ctx ,
382+ node . body . body ,
383+ node . _ownerScope ,
384+ typeParameters
385+ )
329386 if ( node . extends ) {
330387 for ( const ext of node . extends ) {
331388 if (
@@ -543,9 +600,15 @@ function resolveBuiltin(
543600 ctx : TypeResolveContext ,
544601 node : TSTypeReference | TSExpressionWithTypeArguments ,
545602 name : GetSetType < typeof SupportedBuiltinsSet > ,
546- scope : TypeScope
603+ scope : TypeScope ,
604+ typeParameters ?: Record < string , Node >
547605) : ResolvedElements {
548- const t = resolveTypeElements ( ctx , node . typeParameters ! . params [ 0 ] , scope )
606+ const t = resolveTypeElements (
607+ ctx ,
608+ node . typeParameters ! . params [ 0 ] ,
609+ scope ,
610+ typeParameters
611+ )
549612 switch ( name ) {
550613 case 'Partial' : {
551614 const res : ResolvedElements = { props : { } , calls : t . calls }
@@ -1103,14 +1166,7 @@ function moduleDeclToScope(
11031166 return node . _resolvedChildScope
11041167 }
11051168
1106- const scope = new TypeScope (
1107- parentScope . filename ,
1108- parentScope . source ,
1109- parentScope . offset ,
1110- Object . create ( parentScope . imports ) ,
1111- Object . create ( parentScope . types ) ,
1112- Object . create ( parentScope . declares )
1113- )
1169+ const scope = createChildScope ( parentScope )
11141170
11151171 if ( node . body . type === 'TSModuleDeclaration' ) {
11161172 const decl = node . body as TSModuleDeclaration & WithScope
@@ -1124,6 +1180,17 @@ function moduleDeclToScope(
11241180 return ( node . _resolvedChildScope = scope )
11251181}
11261182
1183+ function createChildScope ( parentScope : TypeScope ) {
1184+ return new TypeScope (
1185+ parentScope . filename ,
1186+ parentScope . source ,
1187+ parentScope . offset ,
1188+ Object . create ( parentScope . imports ) ,
1189+ Object . create ( parentScope . types ) ,
1190+ Object . create ( parentScope . declares )
1191+ )
1192+ }
1193+
11271194const importExportRE = / ^ I m p o r t | ^ E x p o r t /
11281195
11291196function recordTypes (
@@ -1262,7 +1329,7 @@ function recordType(
12621329 if ( overwriteId || node . id ) types [ overwriteId || getId ( node . id ! ) ] = node
12631330 break
12641331 case 'TSTypeAliasDeclaration' :
1265- types [ node . id . name ] = node . typeAnnotation
1332+ types [ node . id . name ] = node . typeParameters ? node : node . typeAnnotation
12661333 break
12671334 case 'TSDeclareFunction' :
12681335 if ( node . id ) declares [ node . id . name ] = node
0 commit comments