UNPKG

selectorator

Version:

Simplified generator of reselect selectors

164 lines (160 loc) 7.01 kB
import { DefaultMemoizeFields, CreateSelectorOptions } from 'reselect'; import { Path as Path$1, PathItem, ParsePath } from 'pathington'; interface PathObject { argIndex?: number; path: PathingtonPath; } type PathingtonPath = Path$1 | PathItem; type Path<Params extends unknown[]> = ManualSelectInput<Params> | PathingtonPath | PathObject; type PathStructured<Params extends unknown[]> = Record<string, Path<Params>>; type IsNull<T> = [T] extends [null] ? true : false; type IsUnknown<T> = unknown extends T ? (IsNull<T> extends false ? true : false) : false; type PickArray<Value extends unknown[], Index extends number> = Value[Index]; type PickObject<Value extends object, Key extends keyof Value> = Value[Key]; type WidenUnknown<T extends unknown[], Result extends any[] = []> = T extends [infer Head, ...infer Tail] ? IsUnknown<Head> extends true ? WidenUnknown<Tail, [...Result, any]> : WidenUnknown<Tail, [...Result, Head]> : Result; type PickDeepInternal<Value, Property extends unknown[]> = IsUnknown<Value> extends true ? unknown : Property extends [infer Next, ...infer Rest] ? Value extends object ? Next extends keyof Value ? PickDeepInternal<PickObject<Value, Next>, Rest> : undefined : Value extends unknown[] ? Next extends number ? PickDeepInternal<PickArray<Value, Next>, Rest> : undefined : undefined : Value; type PickDeepInternalNormalized<Value, Property> = Property extends unknown[] ? PickDeepInternal<Value, Property> : Property extends readonly unknown[] ? PickDeepInternal<Value, [...Property]> : any; type PickDeep<Params, Property extends PathingtonPath> = PickDeepInternalNormalized<Params, ParsePath<Property>>; type ManualSelectInput<Params extends unknown[]> = (...params: WidenUnknown<Params>) => any; type SelectInputs<Params extends unknown[], Paths extends unknown[], Values extends unknown[] = []> = Paths extends [ infer Property, ...infer Remaining, ] ? Property extends PathingtonPath ? SelectInputs<Params, Remaining, [...Values, PickDeep<Params[0], Property>]> : Property extends PathObject ? Property['argIndex'] extends number ? SelectInputs<Params, Remaining, [...Values, PickDeep<Params[Property['argIndex']], Property['path']>]> : SelectInputs<Params, Remaining, [...Values, PickDeep<Params[0], Property['path']>]> : Property extends ManualSelectInput<Params> ? SelectInputs<Params, Remaining, [...Values, ReturnType<Property>]> : SelectInputs<Params, Remaining, [...Values, never]> : Values; type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends ( mergedIntersection: infer Intersection, ) => void ? Intersection & Union : never; type Push<T extends any[], V> = [...T, V]; type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends () => infer R ? R : never; type TuplifyUnion<T, L = LastOf<T>, N = [T] extends [never] ? true : false> = true extends N ? [] : Push<TuplifyUnion<Exclude<T, L>>, L>; type ObjectValuesToTuple<T, KS extends any[] = TuplifyUnion<keyof T>, R extends any[] = []> = KS extends [ infer K, ...infer KT, ] ? ObjectValuesToTuple<T, KT, [...R, T[K & keyof T]]> : R; type SelectStructuredInputs<Params extends unknown[], Paths extends Record<string, unknown>> = { [Property in keyof Paths]: Paths[Property] extends PathingtonPath ? PickDeep<Params[0], Paths[Property]> : Paths[Property] extends PathObject ? Paths[Property]['argIndex'] extends number ? Paths[Property]['argIndex'] : PickDeep<Params[0], Paths[Property]['path']> : Paths[Property] extends ManualSelectInput<Params> ? ReturnType<Paths[Property]> : never; }; type ComputeValue<Params extends unknown[], Paths extends unknown[], Result> = ( ...values: SelectInputs<WidenUnknown<Params>, Paths> ) => Result; type StructuredValues<Params extends unknown[], Paths extends Record<string, unknown>> = ObjectValuesToTuple< SelectStructuredInputs<Params, Paths> >; type ComputeStructuredValue<Params extends unknown[], Paths extends Record<string, unknown>, Result> = ( ...values: StructuredValues<Params, Paths> ) => Result; type IdentitySelectorFn<Params extends unknown[], Paths extends unknown[]> = ( ...params: Params ) => SelectInputs<WidenUnknown<Params>, Paths>[0]; type IdentitySelector<Params extends unknown[], Paths extends unknown[]> = IdentitySelectorFn<Params, Paths> & DefaultMemoizeFields; type IdentityStructuredSelectorFn<Params extends unknown[], Paths extends Record<string, unknown>> = ( ...params: Params ) => SelectStructuredInputs<WidenUnknown<Params>, Paths>; type IdentityStructuredSelector< Params extends unknown[], Paths extends Record<string, unknown>, > = IdentityStructuredSelectorFn<Params, Paths> & DefaultMemoizeFields; type StandardSelectorFn<Params extends unknown[], Result> = (...params: Params) => Result; type StandardSelector<Params extends unknown[], Result> = StandardSelectorFn<Params, Result> & DefaultMemoizeFields; /** * Create a selector without any boilerplate code * * @example * import { createSelector } from 'selectorator'; * * interface Item { * name: string; * value: number; * } * * interface State { * items: Item[]; * filter: { * value: string; * } * } * * const getFilteredItems = createSelector<State>()( * ['items', 'filter.value'], * (items, filterValue) => items.filter((item) => item.includes(filterValue)), * ); * * const state = { * items: ['foo', 'bar', 'foo-bar'], * filter: { * value: 'foo' * } * }; * * console.log(getFilteredItems(state)); // ['foo', 'foo-bar']; * console.log(getFilteredItems(state)); // ['foo', 'foo-bar'], pulled from cache; */ declare function createSelector<Args>(options?: CreateSelectorOptions): { <const Paths extends [Path<Args extends unknown[] ? Args : [Args]>]>( paths: Paths, getComputedValue?: undefined, ): IdentitySelector<Args extends unknown[] ? Args : [Args], Paths>; < const Paths extends Array<Path<Args extends unknown[] ? Args : [Args]>>, GetComputedValue extends ComputeValue<Args extends unknown[] ? Args : [Args], Paths, any>, >( paths: Paths, getComputedValue: GetComputedValue, ): StandardSelector<Args extends unknown[] ? Args : [Args], ReturnType<GetComputedValue>>; <const Paths extends PathStructured<Args extends unknown[] ? Args : [Args]>>( paths: Paths, ): IdentityStructuredSelector<Args extends unknown[] ? Args : [Args], Paths>; < const Paths extends PathStructured<Args extends unknown[] ? Args : [Args]>, GetComputedValue extends ComputeStructuredValue<Args extends unknown[] ? Args : [Args], Paths, any>, >( paths: Paths, getComputedValue: GetComputedValue, ): StandardSelector<Args extends unknown[] ? Args : [Args], ReturnType<GetComputedValue>>; }; export { createSelector };