import type { Combine, Contains, IsNever, IsTuple } from "../utils/types"; import type { HKT, Piped, Composed, Kind } from "../utils/hkt"; type Transforms = readonly Transform[]; type Resolve = ((value: T) => R) | null; type Reject = ((reason?: any) => R) | null; type Unwrapped = IsNever< T, never, Composed >; type Wrapped = IsNever>; type All = MonadsTransform extends [] ? Monad : Monad, MonadsTransform>; interface Wrappable { unwrap(fallback?: U): Unwrapped | Promised; } interface Transform extends HKT { readonly extensions: Record; readonly unwrap: this[""]; readonly then: this[""]; readonly accept: any; readonly $: ID; } interface Identity extends Transform<"Identity"> { unwrap: this[""]; then: this[""]; } interface Future extends Transform<"Future"> { unwrap: Promise; then: Awaited; } declare const types: unique symbol; interface Base { then( resolved?: Resolve, Result1>, rejected?: Reject ): Resolved, T, F>; catch( rejected?: Reject ): Resolved, T, F>; finally(handler?: (() => void) | undefined | null): Base; unwrap(fallback?: U): Unwrapped | Promised; expose(): Promised< F, | { data: Awaited>; error: undefined } | { data: undefined; error: Error } >; readonly [Symbol.toStringTag]: string; readonly [types]?: [T, F]; [state: symbol]: any; } type Monad = Base & (F extends [infer U extends Transform, ...any[]] ? Kind : Record); // ======================= UTILS ======================= // type Monadify = T extends Promise ? Monad : T; type Promised = IsNever< T, never, Contains, T> >; type Merged = Monadify extends Monad< infer T1, infer F1 > ? Merged> : [T, F]; type Parsed = Merged extends [ infer T1, infer U1 extends Transforms ] ? Monad : never; type Resolved = IsNever< Wrapped, Parsed, Parsed >; type MonadsType = IsTuple< T, T extends readonly [infer A, ...infer Tail] ? A extends Monad ? [R, ...MonadsType] : A extends Promise ? [R, ...MonadsType] : [A, ...MonadsType] : [], T extends readonly (infer A)[] ? ((A extends Monad ? U : A) extends infer K ? K extends Promise ? U : K : never)[] : never >; type MonadsTransform = IsTuple< T, T extends readonly [infer A, ...infer Tail] ? IsNever extends Monad ? Combine> : IsNever extends Promise ? Combine<[Future], MonadsTransform> : MonadsTransform : [], T extends readonly (infer A)[] ? (A extends Monad ? F : A) extends infer K ? K extends Promise ? [Future] : K extends Transforms ? K : never : never : never >; type Wrapper = { ( value: F["accept"] | Error, fn: (value: Kind | Error) => U ): Kind; }; type Extensions = | { [key in keyof (F["extensions"] & Partial>)]: (F["extensions"] & Monad)[key] extends (..._: infer P) => infer R ? (this: Monad, ..._: P) => R : (F["extensions"] & Monad)[key]; } | Record; export type { MonadsTransform, Extensions, Transform, Unwrapped, Wrappable, Promised, Identity, Wrapped, Wrapper, Resolve, Future, Reject, Monad, All, };