import * as ts from 'typescript' ; import { FileInfo , Constants } from '../types' ; const getTypeReferenceNode = ( fileInfo , utilityTypeName , variableDeclarationName , constants ) => ts . createTypeReferenceNode ( ts . createIdentifier ( utilityTypeName ) , [ ts . createIndexedAccessTypeNode ( ts . createIndexedAccessTypeNode ( ts . createTypeReferenceNode ( ts . createIdentifier ( constants . MODULES ) , undefined ) , ts . createLiteralTypeNode ( ts . createStringLiteral ( fileInfo . nameSpace ) ) ) , ts . createLiteralTypeNode ( ts . createStringLiteral ( variableDeclarationName ) ) ) ] ) ; const getIntersectionTypeNode = ( fileInfos , constants ) => fileInfos . map ( fileInfo => { let current = 0 ; if ( ! fileInfo . fileTreeKeys [ current ] ) { return getTypeReferenceNode ( fileInfo , constants . RETURN_TYPE , constants . STATE , constants ) ; } const visit = ( ) : ts . TypeElement => { if ( fileInfo . fileTreeKeys [ current + 1 ] ) { current ++ ; return ts . createPropertySignature ( undefined , ts . createIdentifier ( fileInfo . fileTreeKeys [ current - 1 ] ) , undefined , ts . createTypeLiteralNode ( [ visit ( ) ] ) , undefined ) ; } else { return ts . createPropertySignature ( undefined , ts . createIdentifier ( fileInfo . fileTreeKeys [ current ] ) , undefined , getTypeReferenceNode ( fileInfo , constants . RETURN_TYPE , constants . STATE , constants ) , undefined ) ; } } ; return ts . createTypeLiteralNode ( [ visit ( ) ] ) ; } ) ; export const rootState = ( fileInfos , constants ) => ts . createTypeAliasDeclaration ( undefined , undefined , ts . createIdentifier ( constants . ROOT_STATE ) , undefined , ts . createIntersectionTypeNode ( getIntersectionTypeNode ( fileInfos , constants ) ) ) ;