import * as tsc from "typescript" ; export namespace GenericAnalyzer { export type Dictionary = WeakMap < tsc . Type , tsc . Type > ; export function analyze ( checker , classNode ) { const dict = new WeakMap ( ) ; explore ( checker , dict , classNode ) ; return dict ; } function explore ( checker , dict , classNode ) { if ( classNode . heritageClauses === undefined ) return ; for ( const heritage of classNode . heritageClauses ) for ( const hType of heritage . types ) { const expression = checker . getTypeAtLocation ( hType . expression ) ; const superNode = expression . symbol . getDeclarations ( ) ! [ 0 ] ; if ( ! tsc . isClassDeclaration ( superNode ) ) continue ; const usages = if_undefined_array ( hType . typeArguments ) ; const parameters = if_undefined_array ( superNode . typeParameters ) ; parameters . forEach ( ( param , index ) => { const paramType = checker . getTypeAtLocation ( param ) ; const usageType = ( usages [ index ] !== undefined ) ? checker . getTypeAtLocation ( usages [ index ] ) : checker . getTypeAtLocation ( param . default ! ) ; dict . set ( paramType , usageType ) ; } ) ; explore ( checker , dict , superNode ) ; } } function if_undefined_array < T > ( array ) { return array !== undefined ? array : [ ] ; } }