@@ -283,8 +283,21 @@ function buildBehaviorInterface (type: M.Interface): string {
283
283
// The main difference with this approaches comes when you are actually using the types. 1 and 2 are good when
284
284
// you are reading an object of that type, while 3 is good when you are writing an object of that type.
285
285
function serializeAdditionalPropertiesType ( type : M . Interface ) : string {
286
- const dictionaryOf = lookupBehavior ( type , 'AdditionalProperties' ) ?? lookupBehavior ( type , 'AdditionalProperty' )
286
+ let dictionaryOf = lookupBehavior ( type , 'AdditionalProperties' ) ?? lookupBehavior ( type , 'AdditionalProperty' )
287
287
if ( dictionaryOf == null ) throw new Error ( `Unknown implements ${ type . name . name } ` )
288
+
289
+ const parent = model . types . find ( t => t . name . name === type . inherits ?. type . name )
290
+ if ( parent != null && parent . kind === 'interface' && parent . generics != null && parent . generics . length === type . inherits ?. generics ?. length ) {
291
+ const map = new Map < M . TypeName , M . ValueOf > ( ) ;
292
+ for ( let i = 0 ; i < parent . generics . length ; i ++ ) {
293
+ map . set ( parent . generics [ i ] , type . inherits . generics [ i ] )
294
+ }
295
+ dictionaryOf = {
296
+ type : dictionaryOf . type ,
297
+ generics : dictionaryOf . generics ?. map ( x => replaceGenerics ( x , map ) )
298
+ }
299
+ }
300
+
288
301
const extendedPropertyTypes = getAllExtendedPropertyTypes ( type . inherits )
289
302
const openGenerics = type . generics ?. map ( t => t . name ) ?? [ ]
290
303
let code = `export interface ${ createName ( type . name ) } Keys${ buildGenerics ( type . generics ) } ${ buildInherits ( type ) } {\n`
@@ -325,6 +338,27 @@ function serializeAdditionalPropertiesType (type: M.Interface): string {
325
338
}
326
339
}
327
340
341
+ function replaceGenerics ( value : M . ValueOf , map : Map < M . TypeName , M . ValueOf > ) : M . ValueOf {
342
+ if ( value . kind !== 'instance_of' ) {
343
+ return value
344
+ }
345
+
346
+ if ( value . generics == null || value . generics . length === 0 ) {
347
+ for ( const entry of map ) {
348
+ if ( entry [ 0 ] . namespace === value . type . namespace && entry [ 0 ] . name === value . type . name ) {
349
+ return entry [ 1 ]
350
+ }
351
+ }
352
+ return value
353
+ }
354
+
355
+ return {
356
+ kind : 'instance_of' ,
357
+ type : value . type ,
358
+ generics : value . generics . map ( x => replaceGenerics ( x , map ) )
359
+ }
360
+ }
361
+
328
362
function lookupBehavior ( type : M . Interface , name : string ) : M . Inherits | null {
329
363
if ( ! type . attachedBehaviors ?. includes ( name ) ) return null // eslint-disable-line
330
364
if ( Array . isArray ( type . behaviors ) ) {
0 commit comments