import type { Selector } from 'reselect'; /** * The NoOptionalParams type is a utility type that checks if a function has optional or default parameters. * If the function has optional or default parameters, it returns a string literal type with an error message. * Otherwise, it returns the original function type. * * This is used to enforce that the combiner function passed to createSelector does not have optional or default parameters, * as memoization relies on the Function.length property, which does not account for optional or default parameters. */ type NoOptionalParams = Parameters extends Required> ? F : 'Combiner cannot have optional or default parameters because memoization relies on Function.length'; export type CreateSelectorFunction = >, const Combiner extends (...args: readonly [...ReturnTypes, ...Args]) => any>(...items: [...Selectors, NoOptionalParams]) => (...args: Selectors['length'] extends 0 ? MergeParams, Parameters> : [StateFromSelectorList, ...MergeParams, Parameters>]) => ReturnType; type StateFromSelectorList = Selectors extends [f: infer F, ...other: infer R] ? StateFromSelector extends StateFromSelectorList ? StateFromSelector : StateFromSelectorList : {}; type StateFromSelector = T extends ((first: infer F, ...args: any[]) => any) ? F : never; type Fn = (...args: any[]) => any; type ReturnTypes = { [Index in keyof FunctionsArray]: FunctionsArray[Index] extends FunctionsArray[number] ? ReturnType : never }; type MergeParams = STypes['length'] extends 0 ? CTypes : MergeParams, DropFirst>; type DropFirst = T extends [any, ...infer Xs] ? Xs : []; export {};