@codeparticle/rdx
Version:
RDX is a module based redux framework that generates boilerplate for you.
238 lines (224 loc) • 7.38 kB
TypeScript
import { L as List, d as Length, K as Key, C as Cast, I as Iteration, c as IterationOf, A as At, P as Pos, N as Next, E as Extends, b as Literal, e as Pop } from './_Internal.d-b77d7bab';
/**
* Get the first entry of `L`
* @param L to extract from
* @returns [[Any]]
* @example
* ```ts
* ```
*/
declare type Head<L extends List> = Length<L> extends 0 ? never : L[0];
/**
* Remove the first item out of a [[List]]
* @param L
* @returns [[List]]
* @example
* ```ts
* ```
*/
declare type Tail<L extends List> = L extends readonly [] ? L : L extends readonly [any?, ...infer LTail] ? LTail : L;
/**
* @ignore
*/
declare type _Path<O, P extends List<Key>, I extends Iteration = IterationOf<0>> = {
0: _Path<At<O, P[Pos<I>]>, P, Next<I>>;
1: O;
}[Extends<Pos<I>, Length<P>>];
/**
* Get in `O` the type of nested properties
* @param O to be inspected
* @param Path to be followed
* @returns [[Any]]
* @example
* ```ts
* ```
*/
declare type Path<O extends any, P extends List<Key>> = _Path<O & {}, P> extends infer X ? Cast<X, any> : never;
/**
* @hidden
*/
declare type _UnionOf<O extends object> = O[keyof O];
/**
* Transform an [[Object]] into an [[Union]]
* @param O to transform
* @returns [[Any]]
* @example
* ```ts
* ```
*/
declare type UnionOf<O extends object> = O extends unknown ? _UnionOf<O> : never;
/**
* Describes the match strategy when matching types
* * `default` : `extends->`
* * `contains->` : X contains Y ([[Contains]]<X, Y>)
* * `extends->` : X extends Y ([[Extends]]<X, Y>)
* * `<-contains` : Y contains X ([[Contains]]<Y, X>)
* * `<-extends` : Y extends X ([[Extends]]<Y, X>)
* * `equals` : X equals Y (([[Equals]]<X, Y>))
*/
declare type Match = 'default' | 'contains->' | 'extends->' | '<-contains' | '<-extends' | 'equals';
/**
* Check whether `A1` is equal to `A2` or not.
* @param A1
* @param A2
* @returns [[Boolean]]
* @example
* ```ts
* import {A} from 'ts-toolbelt'
*
* type test0 = A.Equals<42 | 0, 42 | 0> // true
* type test1 = A.Equals<{a: string}, {b: string}> // false
* type test3 = A.Equals<{a: string}, {readonly a: string}> // false
* ```
*/
declare type Equals<A1 extends any, A2 extends any> = (<A>() => A extends A2 ? 1 : 0) extends (<A>() => A extends A1 ? 1 : 0) ? 1 : 0;
/**
* Check whether `A1` is part of `A2` or not. It works like
* [[Extends]] but [[Boolean]] results are narrowed to [[False]].
* @param A1
* @param A2
* @returns [[Boolean]]
* @example
* ```ts
* type test0 = A.Contains<'a' | 'b', 'b'> // False
* type test1 = A.Contains<'a', 'a' | 'b'> // True
*
* type test2 = A.Contains<{a: string}, {a: string, b: number}> // False
* type test3 = A.Contains<{a: string, b: number}, {a: string}> // True
*
* type test4 = A.Contains<never, never> // False
* /// Nothing cannot contain nothing, use `A.Equals`
* ```
*/
declare type Contains<A1 extends any, A2 extends any> = Extends<A1, A2> extends 1 ? 1 : 0;
/**
* Check whether `A` is similar to `A1` or not. In other words, it is a compact
* type that bundles [[Equals]], [[Extends]], [[Contains]], comparison types.
* @param A to be compared
* @param A1 to compare to
* @param match (?=`'default'`) to change precision
* @returns [[Boolean]]
* @example
* ```ts
* import {A} from 'ts-toolbelt'
*
* type test0 = A.Is<'a', 'a' | 'b', 'extends->'> // True
* type test1 = A.Is<'a' | 'b', 'a', 'extends->'> // Boolean
*
* type test2 = A.Is<'a', 'a' | 'b', '<-extends'> // Boolean
* type test3 = A.Is<'a' | 'b', 'a', '<-extends'> // True
*
* type test4 = A.Is<'a', 'a' | 'b', 'contains->'> // True
* type test5 = A.Is<'a' | 'b', 'a', 'contains->'> // False
*
* type test6 = A.Is<'a', 'a' | 'b', '<-contains'> // False
* type test7 = A.Is<'a' | 'b', 'a', '<-contains'> // True
*
* type test8 = A.Is<'a', 'a' | 'b', 'equals'> // False
* type test9 = A.Is<'b' |'a', 'a' | 'b', 'equals'> // True
* ```
*/
declare type Is<A extends any, A1 extends any, match extends Match = 'default'> = {
'default': Extends<A, A1>;
'contains->': Contains<A, A1>;
'extends->': Extends<A, A1>;
'<-contains': Contains<A1, A>;
'<-extends': Extends<A1, A>;
'equals': Equals<A1, A>;
}[match];
/**
* Extract the part of `U` that matches `M`
* @param U to extract from
* @param M to select with
* @returns [[Union]]
* @example
* ```ts
* ```
*/
declare type Select<U extends any, M extends any, match extends Match = 'default'> = U extends unknown ? {
1: U & M;
0: never;
}[Is<U, M, match>] : never;
/**
* @hidden
*/
declare type _Join<T extends List, D extends string> = T extends [] ? '' : T extends [Literal] ? `${T[0]}` : T extends [Literal, ...infer R] ? `${T[0]}${D}${_Join<R, D>}` : string;
/**
* Concat many literals together
* @param T to concat
* @param D to delimit
*/
declare type Join<T extends List<Literal>, D extends string = ''> = _Join<T, D> extends infer X ? Cast<X, string> : never;
/**
* @ignore
*/
declare type __Split<S extends string, D extends string, T extends string[] = []> = S extends `${infer BS}${D}${infer AS}` ? __Split<AS, D, [...T, BS]> : [...T, S];
/**
* @hidden
*/
declare type _Split<S extends string, D extends string = ''> = D extends '' ? Pop<__Split<S, D>> : __Split<S, D>;
/**
* Split `S` by `D` into a [[List]]
* @param S to split up
* @param D to split at
*/
declare type Split<S extends string, D extends string = ''> = _Split<S, D> extends infer X ? Cast<X, string[]> : never;
/**
* @ignore
*/
declare type Index = number | string;
/**
* @ignore
*/
declare type KeyToIndex<K extends Key, SP extends List<Index>> = number extends K ? Head<SP> : K & Index;
/**
* @ignore
*/
declare type MetaPath<O, D extends string, SP extends List<Index> = [], P extends List<Index> = []> = {
[K in keyof O]: MetaPath<O[K], D, Tail<SP>, [...P, KeyToIndex<K, SP>]> | Join<[...P, KeyToIndex<K, SP>], D>;
};
/**
* @ignore
*/
declare type NextPath<OP> = Select<UnionOf<Exclude<OP, string> & {}>, string>;
/**
* @ignore
*/
declare type ExecPath<A, SP extends List<Index>, Delimiter extends string> = NextPath<Path<MetaPath<A, Delimiter, SP>, SP>>;
/**
* @ignore
*/
declare type HintPath<A, P extends string, SP extends List<Index>, Exec extends string, D extends string> = [Exec] extends [never] ? ExecPath<A, Pop<SP>, D> : Exec | P;
/**
* @ignore
*/
declare type _AutoPath<A, P extends string, D extends string, SP extends List<Index> = Split<P, D>> = HintPath<A, P, SP, ExecPath<A, SP, D>, D>;
/**
* Auto-complete, validate, and query the string path of an object `O`
* @param O to work on
* @param P path of `O`
* @param D (?=`'.'`) delimiter for path
*
* ```ts
* declare function get<O extends object, P extends string>(
* object: O, path: AutoPath<O, P>
* ): Path<O, Split<P, '.'>>
*
* declare const user: User
*
* type User = {
* name: string
* friends: User[]
* }
*
* // works
* const friendName = get(user, 'friends.40.name')
* const friendFriendName = get(user, 'friends.40.friends.12.name')
*
* // errors
* const friendNames = get(user, 'friends.40.names')
* const friendFriendNames = get(user, 'friends.40.friends.12.names')
* ```
*/
declare type AutoPath<O extends any, P extends string, D extends string = '.'> = _AutoPath<O, P, D>;
export { AutoPath as A, Is as I, Match as M, Tail as T };