types.ts

import { ObjectInterface } from "@daybrush/utils";

// CheckType
export type CheckObjectType<T> = T extends ObjectInterface<infer U> ? U : never;
/**
* @typedef
*/
export type CheckIterableType<T> = T extends Iterable<infer U> ? U : T;
/**
* @typedef
*/
export type PureType<T> = T extends infer U | Promise<infer U> ? U : never;
export type CheckPromiseIterableType<T> = PureType<CheckIterableType<T>>;
export type CheckPromiseObjectType<T> = PureType<CheckObjectType<T>>;
export type CheckPromiseType<T, A, B, U = PureType<T>> =
  U | Promise<U> extends T ? A : T extends Promise<any> ? A : B;
export type CheckPromiseReturnType<T, R = T, U = PureType<T>> =
  CheckPromiseType<T, Promise<R>, R, U>;

export type NoPromise<T> = Exclude<T, Promise<any>>;

export type PromiseReturnType<T> = T | Promise<T>;
/**
* @typedef
*/
export type IteratorType<T = any> = Iterable<T> | ObjectInterface<T>;

/**
* @typedef
*/
export type Func<A = any, B = any> = (a: A) => B;

export type CheckReturnType<A, B> = A extends any[] ? B[] : A extends Iterable<any> ? Iterable<B> : ObjectInterface<B>;

// Curry 4
/**
* @typedef
*/
export type Curry4CallbackType<A, B, C, D, E> = (a: A, b: B, c: C, d: D) => E;
/**
* @typedef
*/
export interface Curry4<A, B, C, D, E> {
  <F extends A = A, G extends B = B, H extends C = C, I extends D = D, J extends E = E>
  (a: F): Curry3<G, H, I, J>;
  <F extends A = A, G extends B = B, H extends C = C, I extends D = D, J extends E = E>
  (a: F, b: G): Curry2<H, I, J>;
  <F extends A = A, G extends B = B, H extends C = C, I extends D = D, J extends E = E>
  (a: F, b: G, c: H): Curry1<I, J>;
  <F extends A = A, G extends B = B, H extends C = C, I extends D = D, J extends E = E>
  (a: F, b: G, c: H, d: I): J;
}
// Curry 3
/**
* @typedef
*/
export type Curry3CallbackType<A, B, C, D> = (a: A, b: B, c: C) => D;
/**
* @typedef
* @extends Curry3CallbackType
*/
export interface Curry3<A, B, C, D> {
  <E extends A = A, F extends B = B, G extends C = C, H extends D = D>
    (a: E): Curry2<F, G, H>;
  <E extends A = A, F extends B = B, G extends C = C, H extends D = D>
    (a: E, b: F): Curry1<G, H>;
  <E extends A = A, F extends B = B, G extends C = C, H extends D = D>
    (a: E, b: F, c: G): H;
}
// Curry 2
export type Curry2CallbackType<A, B, C> = (a: A, b: B) => C;
/**
* @typedef
*/
export interface Curry2<A = any, B = any, C = any> {
  <D extends A = A, E extends B = B, F extends C = C>(a: D): Curry1<E, F>;
  <D extends A = A, E extends B = B, F extends C = C>(a: D, b: E): F;
}
// Curry 1
/**
* @typedef
*/
export type  Curry1CallbackType<A, B> = (a: A) => B;

/**
* @typedef
*/
export type Curry1<A = any, B = any> = <C extends A = A, D extends B = B>(a: C) => D;