import { IValidationContext , IValidationResult , typeCheckSuccess , typeCheckFailure , flattenTypeErrors , isType , TypeFlags , IType , fail , isPlainObject , IAnyType , IValidationError , IModelType , ModelProperties , ModelInstanceType , ModelSnapshotType2 , ModelCreationType2 , _NotCustomized , AnyObjectNode , BaseType , devMode , assertIsType , assertArg } from "../../internal" ; export type ITypeDispatcher = ( snapshot : any ) => IAnyType ; export interface UnionOptions { eager ? : boolean ; dispatcher ? : ITypeDispatcher ; } internal hidden export class Union extends BaseType < any , any , any > { private readonly _dispatcher ? : ITypeDispatcher ; private readonly _eager : boolean = true ; get flags ( ) { let result = TypeFlags . Union ; this . _types . forEach ( ( type ) => { result |= type . flags ; } ) ; return result ; } constructor ( name , private readonly _types , options ? ) { super ( name ) ; options = { eager : true , dispatcher : undefined , ... options } ; this . _dispatcher = options . dispatcher ; if ( ! options . eager ) this . _eager = false ; } isAssignableFrom ( type ) { return this . _types . some ( ( subType ) => subType . isAssignableFrom ( type ) ) ; } describe ( ) { return "(" + this . _types . map ( ( factory ) => factory . describe ( ) ) . join ( " | " ) + ")" ; } instantiate ( parent , subpath , environment , initialValue ) { const type = this . determineType ( initialValue , undefined ) ; if ( ! type ) throw fail ( "No matching type for union " + this . describe ( ) ) ; return type . instantiate ( parent , subpath , environment , initialValue ) ; } reconcile ( current , newValue , parent , subpath ) { const type = this . determineType ( newValue , current . getReconciliationType ( ) ) ; if ( ! type ) throw fail ( "No matching type for union " + this . describe ( ) ) ; return type . reconcile ( current , newValue , parent , subpath ) ; } determineType ( value , reconcileCurrentType ) { if ( this . _dispatcher ) { return this . _dispatcher ( value ) ; } if ( reconcileCurrentType ) { if ( reconcileCurrentType . is ( value ) ) { return reconcileCurrentType ; } return this . _types . filter ( ( t ) => t !== reconcileCurrentType ) . find ( ( type ) => type . is ( value ) ) ; } else { return this . _types . find ( ( type ) => type . is ( value ) ) ; } } isValidSnapshot ( value , context ) { if ( this . _dispatcher ) { return this . _dispatcher ( value ) . validate ( value , context ) ; } const allErrors = [ ] ; let applicableTypes = 0 ; for ( let i = 0 ; i < this . _types . length ; i ++ ) { const type = this . _types [ i ] ; const errors = type . validate ( value , context ) ; if ( errors . length === 0 ) { if ( this . _eager ) return typeCheckSuccess ( ) ; else applicableTypes ++ ; } else { allErrors . push ( errors ) ; } } if ( applicableTypes === 1 ) return typeCheckSuccess ( ) ; return typeCheckFailure ( context , value , "No type is applicable for the union" ) . concat ( flattenTypeErrors ( allErrors ) ) ; } getSubTypes ( ) { return this . _types ; } } hidden export type _CustomCSProcessor < T > = Exclude < T , _NotCustomized > extends never ? _NotCustomized : Exclude < T , _NotCustomized > ; hidden export interface ITypeUnion < C , S , T > extends IType < _CustomCSProcessor < C > , _CustomCSProcessor < S > , T > { } export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB > ( A , B ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB > ( options , A , B ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC > ( A , B , C ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC > ( options , A , B , C ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD > ( A , B , C , D ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD > ( options , A , B , C , D ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE > ( A , B , C , D , E ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE > ( options , A , B , C , D , E ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF > ( A , B , C , D , E , F ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF > ( options , A , B , C , D , E , F ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF , PG extends ModelProperties , OG , FCG , FSG > ( A , B , C , D , E , F , G ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF , PG extends ModelProperties , OG , FCG , FSG > ( options , A , B , C , D , E , F , G ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF , PG extends ModelProperties , OG , FCG , FSG , PH extends ModelProperties , OH , FCH , FSH > ( A , B , C , D , E , F , G , H ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF , PG extends ModelProperties , OG , FCG , FSG , PH extends ModelProperties , OH , FCH , FSH > ( options , A , B , C , D , E , F , G , H ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF , PG extends ModelProperties , OG , FCG , FSG , PH extends ModelProperties , OH , FCH , FSH , PI extends ModelProperties , OI , FCI , FSI > ( A , B , C , D , E , F , G , H , I ) ; export function union < PA extends ModelProperties , OA , FCA , FSA , PB extends ModelProperties , OB , FCB , FSB , PC extends ModelProperties , OC , FCC , FSC , PD extends ModelProperties , OD , FCD , FSD , PE extends ModelProperties , OE , FCE , FSE , PF extends ModelProperties , OF , FCF , FSF , PG extends ModelProperties , OG , FCG , FSG , PH extends ModelProperties , OH , FCH , FSH , PI extends ModelProperties , OI , FCI , FSI > ( options , A , B , C , D , E , F , G , H , I ) ; export function union < CA , SA , TA , CB , SB , TB > ( A , B ) ; export function union < CA , SA , TA , CB , SB , TB > ( options , A , B ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC > ( A , B , C ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC > ( options , A , B , C ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD > ( A , B , C , D ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD > ( options , A , B , C , D ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE > ( A , B , C , D , E ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE > ( options , A , B , C , D , E ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF > ( A , B , C , D , E , F ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF > ( options , A , B , C , D , E , F ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF , CG , SG , TG > ( A , B , C , D , E , F , G ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF , CG , SG , TG > ( options , A , B , C , D , E , F , G ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF , CG , SG , TG , CH , SH , TH > ( A , B , C , D , E , F , G , H ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF , CG , SG , TG , CH , SH , TH > ( options , A , B , C , D , E , F , G , H ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF , CG , SG , TG , CH , SH , TH , CI , SI , TI > ( A , B , C , D , E , F , G , H , I ) ; export function union < CA , SA , TA , CB , SB , TB , CC , SC , TC , CD , SD , TD , CE , SE , TE , CF , SF , TF , CG , SG , TG , CH , SH , TH , CI , SI , TI > ( options , A , B , C , D , E , F , G , H , I ) ; export function union ( ... types ) ; export function union ( dispatchOrType , ... otherTypes ) ; param optionsOrType param otherTypes returns export function union ( optionsOrType , ... otherTypes ) { const options = isType ( optionsOrType ) ? undefined : optionsOrType ; const types = isType ( optionsOrType ) ? [ optionsOrType , ... otherTypes ] : otherTypes ; const name = "(" + types . map ( ( type ) => type . name ) . join ( " | " ) + ")" ; if ( devMode ( ) ) { if ( options ) { assertArg ( options , ( o ) => isPlainObject ( o ) , "object { eager?: boolean, dispatcher?: Function }" , 1 ) ; } types . forEach ( ( type , i ) => { assertIsType ( type , options ? i + 2 : i + 1 ) ; } ) ; } return new Union ( name , types , options ) ; } param type returns export function isUnionType < IT extends IAnyType > ( type ) { return ( type . flags & TypeFlags . Union ) > 0 ; }