UNPKG

7.7 kBTypeScriptView Raw
1import type { MergeParameters } from './versionedTypes';
2export type { MergeParameters } from './versionedTypes';
3/** A standard selector function, which takes three generic type arguments:
4 * @param State The first value, often a Redux root state object
5 * @param Result The final result returned by the selector
6 * @param Params All additional arguments passed into the selector
7 */
8export type Selector<State = any, Result = unknown, Params extends never | readonly any[] = any[]> = [Params] extends [never] ? (state: State) => Result : (state: State, ...params: Params) => Result;
9/** Selectors generated by Reselect have several additional fields attached: */
10export interface OutputSelectorFields<Combiner extends UnknownFunction, Keys> {
11 /** The final function passed to `createSelector` */
12 resultFunc: Combiner;
13 /** The same function, memoized */
14 memoizedResultFunc: Combiner & Keys;
15 /** Returns the last result calculated by the selector */
16 lastResult: () => ReturnType<Combiner>;
17 /** An array of the input selectors */
18 dependencies: SelectorArray;
19 /** Counts the number of times the output has been recalculated */
20 recomputations: () => number;
21 /** Resets the count of recomputations count to 0 */
22 resetRecomputations: () => number;
23}
24/** Represents the actual selectors generated by `createSelector`.
25 * The selector is:
26 * - "a function that takes this state + params and returns a result"
27 * - plus the attached additional fields
28 */
29export type OutputSelector<S extends SelectorArray, Result, Combiner extends UnknownFunction, Params extends readonly any[] = never, // MergeParameters<S>
30Keys = {}> = Selector<GetStateFromSelectors<S>, Result, Params> & OutputSelectorFields<Combiner, Keys>;
31/** A selector that is assumed to have one additional argument, such as
32 * the props from a React component
33 */
34export type ParametricSelector<State, Props, Result> = Selector<State, Result, [
35 Props,
36 ...any
37]>;
38/** A generated selector that is assumed to have one additional argument */
39export type OutputParametricSelector<State, Props, Result, Combiner extends UnknownFunction, Keys = {}> = ParametricSelector<State, Props, Result> & OutputSelectorFields<Combiner, Keys>;
40/** An array of input selectors */
41export type SelectorArray = ReadonlyArray<Selector>;
42/** A standard function returning true if two values are considered equal */
43export type EqualityFn = (a: any, b: any) => boolean;
44/** Extracts an array of all return types from all input selectors */
45export type SelectorResultArray<Selectors extends SelectorArray> = ExtractReturnType<Selectors>;
46/** Determines the combined single "State" type (first arg) from all input selectors */
47export type GetStateFromSelectors<S extends SelectorArray> = MergeParameters<S>[0];
48/** Determines the combined "Params" type (all remaining args) from all input selectors */
49export type GetParamsFromSelectors<S extends SelectorArray, RemainingItems extends readonly unknown[] = Tail<MergeParameters<S>>> = RemainingItems;
50/** Any function with arguments */
51export type UnknownFunction = (...args: any[]) => any;
52/** Extract the return type from all functions as a tuple */
53export type ExtractReturnType<T extends readonly UnknownFunction[]> = {
54 [index in keyof T]: T[index] extends T[number] ? ReturnType<T[index]> : never;
55};
56/** First item in an array */
57export type Head<T> = T extends [any, ...any[]] ? T[0] : never;
58/** All other items in an array */
59export type Tail<A> = A extends [any, ...infer Rest] ? Rest : never;
60/** Last item in an array. Recursion also enables this to work with rest syntax - where the type of rest is extracted */
61export type ReverseHead<S extends readonly unknown[][]> = Tail<S> extends [
62 unknown
63] ? S : Tail<S> extends readonly unknown[][] ? ReverseHead<Tail<S>> : never;
64/** All elements in array except last
65 *
66 * Recursion makes this work also when rest syntax has been used
67 * Runs _ReverseTail twice, because first pass turns last element into "never", and second pass removes it.
68 **/
69export type ReverseTail<S> = _ReverseTail<_ReverseTail<S>>;
70type _ReverseTail<S> = Tail<S> extends [unknown] ? [Head<S>] : Tail<S> extends unknown[] ? [Head<S>, ..._ReverseTail<Tail<S>>] : never;
71/** Extract only numeric keys from an array type */
72export type AllArrayKeys<A extends readonly any[]> = A extends any ? {
73 [K in keyof A]: K;
74}[number] : never;
75export type List<A = any> = ReadonlyArray<A>;
76export type Has<U, U1> = [U1] extends [U] ? 1 : 0;
77/** The infamous "convert a union type to an intersection type" hack
78 * Source: https://github.com/sindresorhus/type-fest/blob/main/source/union-to-intersection.d.ts
79 * Reference: https://github.com/microsoft/TypeScript/issues/29594
80 */
81export type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : never;
82/**
83 * Assorted util types for type-level conditional logic
84 * Source: https://github.com/KiaraGrouwstra/typical
85 */
86export type Bool = '0' | '1';
87export type Obj<T> = {
88 [k: string]: T;
89};
90export type And<A extends Bool, B extends Bool> = ({
91 1: {
92 1: '1';
93 } & Obj<'0'>;
94} & Obj<Obj<'0'>>)[A][B];
95export type Matches<V, T> = V extends T ? '1' : '0';
96export type IsArrayType<T> = Matches<T, any[]>;
97export type Not<T extends Bool> = {
98 '1': '0';
99 '0': '1';
100}[T];
101export type InstanceOf<V, T> = And<Matches<V, T>, Not<Matches<T, V>>>;
102export type IsTuple<T extends {
103 length: number;
104}> = And<IsArrayType<T>, InstanceOf<T['length'], number>>;
105/**
106 * Code to convert a union of values into a tuple.
107 * Source: https://stackoverflow.com/a/55128956/62937
108 */
109type Push<T extends any[], V> = [...T, V];
110type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends () => infer R ? R : never;
111export type TuplifyUnion<T, L = LastOf<T>, N = [T] extends [never] ? true : false> = true extends N ? [] : Push<TuplifyUnion<Exclude<T, L>>, L>;
112/**
113 * Converts "the values of an object" into a tuple, like a type-level `Object.values()`
114 * Source: https://stackoverflow.com/a/68695508/62937
115 */
116export type ObjValueTuple<T, KS extends any[] = TuplifyUnion<keyof T>, R extends any[] = []> = KS extends [infer K, ...infer KT] ? ObjValueTuple<T, KT, [...R, T[K & keyof T]]> : R;
117/** Utility type to infer the type of "all params of a function except the first", so we can determine what arguments a memoize function accepts */
118export type DropFirst<T extends unknown[]> = T extends [unknown, ...infer U] ? U : never;
119/**
120 * Expand an item a single level, or recursively.
121 * Source: https://stackoverflow.com/a/69288824/62937
122 */
123export type Expand<T> = T extends (...args: infer A) => infer R ? (...args: Expand<A>) => Expand<R> : T extends infer O ? {
124 [K in keyof O]: O[K];
125} : never;
126export type ExpandRecursively<T> = T extends (...args: infer A) => infer R ? (...args: ExpandRecursively<A>) => ExpandRecursively<R> : T extends object ? T extends infer O ? {
127 [K in keyof O]: ExpandRecursively<O[K]>;
128} : never : T;
129type Identity<T> = T;
130/**
131 * Another form of type value expansion
132 * Source: https://github.com/microsoft/TypeScript/issues/35247
133 */
134export type Mapped<T> = Identity<{
135 [k in keyof T]: T[k];
136}>;
137export type If2<B extends Boolean2, Then, Else = never> = B extends 1 ? Then : Else;
138export type Boolean2 = 0 | 1;
139export type Key = string | number | symbol;
140export type BuiltIn = Function | Error | Date | {
141 readonly [Symbol.toStringTag]: string;
142} | RegExp | Generator;