import { DEFAULT_GENERIC_PARAMETER_TYPE } from "../constants" ; import { isSimpleTypeLiteral , PRIMITIVE_TYPE_KINDS , SimpleType , SimpleTypeBooleanLiteral , SimpleTypeGenericArguments , SimpleTypeNull , SimpleTypeNumberLiteral , SimpleTypeTuple , SimpleTypeUndefined } from "../simple-type" ; import { resolveType } from "./resolve-type" ; param tuple export function getTupleLengthType ( tuple ) { if ( tuple . rest ) { return { kind : "NUMBER" } ; } const minLength = tuple . members . filter ( member => ! member . optional ) . length ; if ( minLength === tuple . members . length ) { return { kind : "NUMBER_LITERAL" , value : minLength } ; } return { kind : "UNION" , types : new Array ( tuple . members . length - minLength + 1 ) . fill ( 0 ) . map ( ( _ , i ) => ( { kind : "NUMBER_LITERAL" , value : minLength + i } as SimpleTypeNumberLiteral ) ) } ; } export function simplifySimpleTypes ( types ) { let newTypes = [ ... types ] ; const NULLABLE_TYPE_KINDS = [ "UNDEFINED" , "NULL" ] ; newTypes = newTypes . filter ( ( type , i ) => { if ( isSimpleTypeLiteral ( type ) ) { return ! newTypes . slice ( 0 , i ) . some ( newType => newType . kind === type . kind && newType . value === type . value ) ; } if ( PRIMITIVE_TYPE_KINDS . includes ( type . kind ) || NULLABLE_TYPE_KINDS . includes ( type . kind ) ) { return ! newTypes . slice ( 0 , i ) . some ( t => t . kind === type . kind ) ; } return true ; } ) ; const booleanLiteralTypes = newTypes . filter ( ( t ) : t is SimpleTypeBooleanLiteral => t . kind === "BOOLEAN_LITERAL" ) ; if ( booleanLiteralTypes . find ( t => t . value === true ) != null && booleanLiteralTypes . find ( t => t . value === false ) != null ) { newTypes = [ ... newTypes . filter ( type => type . kind !== "BOOLEAN_LITERAL" ) , { kind : "BOOLEAN" } ] ; } const nullableTypes = newTypes . filter ( ( t ) : t is SimpleTypeUndefined | SimpleTypeNull => NULLABLE_TYPE_KINDS . includes ( t . kind ) ) ; if ( nullableTypes . length > 0 ) { newTypes = [ ... newTypes . filter ( t => ! NULLABLE_TYPE_KINDS . includes ( t . kind ) ) , ... nullableTypes . sort ( ( t1 , t2 ) => ( t1 . kind === "NULL" ? ( t2 . kind === "UNDEFINED" ? - 1 : 0 ) : t2 . kind === "NULL" ? 1 : 0 ) ) ] ; } return newTypes ; } export function extendTypeParameterMap ( genericType , existingMap ) { const target = resolveType ( genericType . target , existingMap ) ; if ( "typeParameters" in target ) { const parameterEntries = ( target . typeParameters || [ ] ) . map ( ( parameter , i ) => { const typeArg = genericType . typeArguments [ i ] ; const resolvedTypeArg = typeArg == null ? DEFAULT_GENERIC_PARAMETER_TYPE : resolveType ( typeArg , existingMap ) ; return [ parameter . name , resolvedTypeArg ] as [ string , SimpleType ] ; } ) ; const allParameterEntries = [ ... existingMap . entries ( ) , ... parameterEntries ] ; return new Map ( allParameterEntries ) ; } return existingMap ; }