UNPKG

shades

Version:

Lens-like functionality with a lodash-style interface.

122 lines (103 loc) 2.99 kB
// Minimum TypeScript Version: 3.4 // prettier-ignore export type Functor<F, A, B> = F extends A[] ? B[] : F extends { [key: string]: A } ? { [key: string]: B } : F extends Set<A> ? Set<B> : F extends Map<infer K, A> ? Map<K, B> : F extends Promise<A> ? Promise<B> : never; // prettier-ignore export type Unpack<F> = F extends Array<infer A> ? A : F extends Set<infer A> ? A : F extends Map<any, infer A> ? A : F extends Promise<infer A> ? A : F extends { [n: string]: infer A } ? A : F extends { [n: number]: infer A } ? A : F extends Record<string, infer A> ? A : F extends Record<number, infer A> ? A : F extends Record<symbol, infer A> ? A : never; export type HasKey<K extends string, V = any> = | { [_ in K]: V } | { [_ in K]?: V | undefined }; export interface ErrorCannotLensIntoOptionalKey<T, K> { error: 'You have tried to lens through an optional key. Consider using `fill` to provide defaults to your object'; _val: T; _key: K; } // prettier-ignore export type KeyAt<T, K extends string> = [T] extends [undefined] ? undefined: [T] extends [null] ? null : [T] extends [{ [_ in K]: any }] ? T[K] : [T] extends [{ [_ in K]?: any }] ? T[K] : ErrorCannotLensIntoOptionalKey<T, K>; export type Collection<V, K = any> = | V[] | { [key: string]: V } | Map<K, V> | Set<V>; export type Container<V, K = any> = Collection<V, K> | Promise<V>; export type Indexable<V = any> = V[] | Map<number, V>; export type Index<C> = C extends Indexable<infer V> ? V : never; export type InputType<F, Return = any> = F extends (arg: infer A) => Return ? A : never; export type HasPattern<Pattern> = { [K in keyof Pattern]: | Pattern[K] | InputType<Pattern[K]> | (Pattern[K] extends (a: any) => any ? never : HasPattern<Pattern[K]>) }; export type FillingPattern<Pattern> = { [K in keyof Pattern]?: Pattern[K] | FillingPattern<Pattern[K]> }; export type Fill<T extends FillingPattern<P>, P> = { [K in Exclude<keyof T, keyof P>]: T[K] } & { [K in keyof P]: P[K] }; export type Fn0<Out> = () => Out; export type Fn1<A, Out> = (a: A) => Out; export type Fn2<A, B, Out> = (a: A, b: B) => Out; export type Fn3<A, B, C, Out> = (a: A, b: B, c: C) => Out; export type Fn4<A, B, C, D, Out> = (a: A, b: B, c: C, d: D) => Out; export type Fn5<A, B, C, D, E, Out> = (a: A, b: B, c: C, d: D, e: E) => Out; export type Fn6<A, B, C, D, E, F, Out> = ( a: A, b: B, c: C, d: D, e: E, f: F ) => Out; export type Fn7<A, B, C, D, E, F, G, Out> = ( a: A, b: B, c: C, d: D, e: E, f: F, g: G ) => Out; export type Fn8<A, B, C, D, E, F, G, H, Out> = ( a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H ) => Out; export interface Traversal<Item> { get(s: Collection<Item>): Collection<Item>; mod(f: (a: Item) => Item): (s: Collection<Item>) => Collection<Item>; traversal?: true; } export interface Lens<S, A> { get(s: S): A; mod(f: (a: A) => A): (s: S) => S; traversal?: false; }