import type * as ts from 'typescript' ; import { Scope } from '../../scope/scope' ; import { core } from '../../core/core' ; import { GetCallExpressionType } from '../callExpression/callExpression' ; import { TypescriptHelper } from '../helper/helper' ; import { GetTypeImport } from './typeImport' ; export function GetTypes ( nodes , scope ) { let newNodes = [ ] ; nodes . forEach ( ( node ) => { const type = GetType ( node , scope ) ; if ( core . ts . isUnionTypeNode ( type ) ) { const unionTypes = GetTypes ( type . types , scope ) ; newNodes = newNodes . concat ( unionTypes ) ; } else if ( core . ts . isIntersectionTypeNode ( type ) ) { const intersectionTypes = GetTypes ( type . types , scope ) ; const hasLiteralOrPrimitive = intersectionTypes . some ( ( intersectionType ) => TypescriptHelper . IsLiteralOrPrimitive ( intersectionType ) ) ; if ( ! hasLiteralOrPrimitive ) { newNodes = newNodes . concat ( intersectionTypes ) ; } } else { newNodes . push ( type ) ; } } ) ; return newNodes ; } export function GetType ( node , scope ) { if ( core . ts . isTypeReferenceNode ( node ) ) { const declaration = TypescriptHelper . GetDeclarationFromNode ( node . typeName ) ; const type = GetType ( declaration , scope ) ; if ( type . kind === core . ts . SyntaxKind . InterfaceDeclaration || type . kind === core . ts . SyntaxKind . ClassDeclaration || type . kind === core . ts . SyntaxKind . TypeLiteral ) { return node ; } return type ; } if ( core . ts . isThisTypeNode ( node ) ) { const declaration = TypescriptHelper . GetDeclarationFromNode ( node ) ; return GetType ( declaration , scope ) ; } if ( core . ts . isTypeAliasDeclaration ( node ) ) { return GetType ( node . type , scope ) ; } if ( core . ts . isImportSpecifier ( node ) || core . ts . isImportClause ( node ) ) { const importType = GetTypeImport ( node ) ; return GetType ( importType , scope ) ; } if ( core . ts . isTypeOperatorNode ( node ) ) { return GetType ( node . type , scope ) ; } if ( core . ts . isParenthesizedTypeNode ( node ) ) { return GetType ( node . type , scope ) ; } if ( core . ts . isCallExpression ( node ) ) { return GetType ( GetCallExpressionType ( node ) , scope ) ; } return node ; }