// TypeScript Version: 3.4 export type Nullable = T | U; export type Length = T["length"]; export type Pos = Length; export type Next = Prepend; export type Cast = T extends Y ? T : Y; export type Head = T extends [any, ...any[]] ? T[0] : never; export type Second = T extends [any, any, ...any[]] ? T[1] : never; export type Tail = ((...a: T) => any) extends ((h: any, ...a: infer U) => any) ? U : never; export type HasTail = T extends ([] | [any]) ? false : true; export type IsEmpty = T extends [] ? false : true; export type Last = { 0: Last>; 1: Head; }[ HasTail extends true ? 0 : 1 ]; export type Reverse = { 0: Reverse], R>, Next>; 1: R; }[ Pos extends Length ? 1 : 0 ]; export type Prepend = ((e: E, ...a: T) => any) extends ((...a: infer U) => any) ? U : never; export type Drop = { 0: Drop, Prepend>; 1: T; }[ Length extends N ? 1 : 0 ]; export type Find = { 0: Find>; 1: Head; }[ Head extends E ? 1 : Length extends 0 ? never : 0 ]; // type ft = Find; export type Iter = Iterable | AsyncIterable; // | IterableIterator | AsyncIterableIterator | T[]; export type ExtractPromise = T extends Promise ? PT : T; export type EP = ExtractPromise; export type ExtractMap = T extends Map ? [K, V] : unknown; export type ExtractMapKey = T extends Map ? K : unknown; export type ExtractMapValue = T extends Map ? V : unknown; /** * Non-Promise Iter Flat */ export type Flat = T extends Iter ? E0 : T; /** * Promise Iter Flat */ export type PFlat = EP>>; /** * Non-Promise Iter Deep Flat */ export type DFlat = T extends Iter ? E0 extends Iter ? E1 extends Iter ? E2 extends Iter ? E3 extends Iter ? E4 extends Iter ? E5 extends Iter ? E6 extends Iter ? E7 extends Iter ? E8 extends Iter ? E9 extends Iter ? E10 extends Iter ? E11 : // 12 E10 : E9 : E8 : E7 : E6 : E5 : E4 : E3 : E2 : E1 : E0 : T; /** * Promise Iter Deep Flat */ export type PDFlat = EP>>>>>>>>>>>>>>; /** * Internal Type */ export type FlatForInternalFn = T extends Iter ? E extends Promise ? PE : E : unknown; export type PickElements = { 0: PickElements, Prepend : Second, I>>; 1: Head | Flat; 2: Second | Flat; }[ Length extends 0 ? N extends 0 ? 1 : 2 : 0 ]; export type ReturnTypeIfFunction = T extends (...args: any) => any ? ReturnType : T; /** * if PickElements is () => string | () => number * ReturnType> error */ export type ReturnTypePickElements = { 0: ReturnTypePickElements, Prepend> : ReturnTypeIfFunction>, I>>; 1: ReturnTypeIfFunction> | Flat; 2: ReturnTypeIfFunction> | Flat; }[ Length extends 0 ? N extends 0 ? 1 : 2 : 0 ]; export type PairRepeat = { 0: PairRepeat>>; 1: I; }[ Length extends N ? 1 : 0 ]; export interface CurriedFunction2 { (t1: T1): (t2: T2) => R; (t1: T1, t2: T2): R; } export interface CurriedFunction3 { (t1: T1): CurriedFunction2; (t1: T1, t2: T2): (t3: T3) => R; (t1: T1, t2: T2, t3: T3): R; } export interface CurriedFunction4 { (t1: T1): CurriedFunction3; (t1: T1, t2: T2): CurriedFunction2; (t1: T1, t2: T2, t3: T3): (t4: T4) => R; (t1: T1, t2: T2, t3: T3, t4: T4): R; } export interface CurriedFunction5 { (t1: T1): CurriedFunction4; (t1: T1, t2: T2): CurriedFunction3; (t1: T1, t2: T2, t3: T3): CurriedFunction2; (t1: T1, t2: T2, t3: T3, t4: T4): (t5: T5) => R; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): R; } export interface CurriedFunction6 { (t1: T1): CurriedFunction5; (t1: T1, t2: T2): CurriedFunction4; (t1: T1, t2: T2, t3: T3): CurriedFunction3; (t1: T1, t2: T2, t3: T3, t4: T4): CurriedFunction2; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): (t6: T6) => R; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6): R; } export interface CurriedFunction7 { (t1: T1): CurriedFunction6; (t1: T1, t2: T2): CurriedFunction5; (t1: T1, t2: T2, t3: T3): CurriedFunction4; (t1: T1, t2: T2, t3: T3, t4: T4): CurriedFunction3; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): CurriedFunction2; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6): (t7: T7) => R; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7): R; } export interface CurriedFunction8 { (t1: T1): CurriedFunction7; (t1: T1, t2: T2): CurriedFunction6; (t1: T1, t2: T2, t3: T3): CurriedFunction5; (t1: T1, t2: T2, t3: T3, t4: T4): CurriedFunction4; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): CurriedFunction3; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6): CurriedFunction2; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7): (t8: T8) => R; (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8): R; } export type Accumulator = (acc: T, elem: T) => any; export type FlatAccumulator = (acc: FlatForInternalFn, elem: FlatForInternalFn) => any; export type ArrayN = T extends any[] ? T[N] : T; export type AssociateMap = Map>, ArrayN<1, ExtractPromise>>; export type InnerJoinObject = { [P in keyof T1 | keyof T2]: P extends keyof T1 ? T1[P] : P extends keyof T2 ? T2[P] : unknown }; export type InnerJoinMap = Map ? T2 extends Map ? K1 | K2 : unknown : unknown, T1 extends Map ? T2 extends Map ? V1 | V2 : unknown : unknown>; // export type InnerJoinCustomIterable any; } & Iter, T2 extends { set: (...arg: any[]) => any; } & Iter> = AsyncIterableIterator; // type InnerJoinObjectTest1 = InnerJoinObject<{ id: number; name: string; }, { id: number; length: number; }>; // type InnerJoinObjectTest2 = InnerJoinObject<{ id: number; length: number; }, { id: number; name: string; }>; // type InnerJoinMapTest1 = InnerJoinMap, Map<"string" | "number", (string | number)[]>>; // type InnerJoinMapTest2 = InnerJoinMap, Map<"string" | "number" | "object", (string | number | null)[]>>; export type OuterJoinObject = { [P in keyof T1 | keyof T2]: P extends keyof T1 ? T1[P] : P extends keyof T2 ? T2[P] | undefined : unknown }; /** * K2, V2 is optional, but I can't implementation that type. */ export type OuterJoinMap = Map ? T2 extends Map ? K1 | K2 : unknown : unknown, T1 extends Map ? T2 extends Map ? V1 | V2 : unknown : unknown>; // type OuterJoinObjectTest = OuterJoinObject<{ id: number; value: number; }, { id: number; name: string; }>; // type OuterJoinMapTest = OuterJoinMap, Map>; /* ExpectType OuterJoinObjectTest { id: number; value: number; name: string | undefined; } */ export type MergeObject = { 0: MergeObject, T>, Drop<1, P>>; 1: T; }[ IsEmpty

extends true ? 0 : 1 ]; export type LiteralWrapper = T extends number ? number : T extends string ? string : T;