UNPKG

react-redux

Version:

Official React bindings for Redux

278 lines (255 loc) 9.14 kB
/* eslint-disable no-unused-vars */ // TODO Ignoring all unused variables for now import { ClassAttributes, Component, ComponentClass, ComponentType, StatelessComponent, Context, NamedExoticComponent, } from 'react' import { Action, ActionCreator, AnyAction, Dispatch, Store } from 'redux' // import hoistNonReactStatics = require('hoist-non-react-statics'); import type { NonReactStatics } from 'hoist-non-react-statics' export type FixTypeLater = any export type EqualityFn<T> = (a: T | undefined, b: T | undefined) => boolean /** * This interface can be augmented by users to add default types for the root state when * using `react-redux`. * Use module augmentation to append your own type definition in a your_custom_type.d.ts file. * https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation */ // tslint:disable-next-line:no-empty-interface export interface DefaultRootState {} export type AnyIfEmpty<T extends object> = keyof T extends never ? any : T export type RootStateOrAny = AnyIfEmpty<DefaultRootState> // Omit taken from https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>> export type DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never export interface DispatchProp<A extends Action = AnyAction> { dispatch: Dispatch<A> } export type AdvancedComponentDecorator<TProps, TOwnProps> = ( component: ComponentType<TProps> ) => ComponentType<TOwnProps> /** * A property P will be present if: * - it is present in DecorationTargetProps * * Its value will be dependent on the following conditions * - if property P is present in InjectedProps and its definition extends the definition * in DecorationTargetProps, then its definition will be that of DecorationTargetProps[P] * - if property P is not present in InjectedProps then its definition will be that of * DecorationTargetProps[P] * - if property P is present in InjectedProps but does not extend the * DecorationTargetProps[P] definition, its definition will be that of InjectedProps[P] */ export type Matching<InjectedProps, DecorationTargetProps> = { [P in keyof DecorationTargetProps]: P extends keyof InjectedProps ? InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : InjectedProps[P] : DecorationTargetProps[P] } /** * a property P will be present if : * - it is present in both DecorationTargetProps and InjectedProps * - InjectedProps[P] can satisfy DecorationTargetProps[P] * ie: decorated component can accept more types than decorator is injecting * * For decoration, inject props or ownProps are all optionally * required by the decorated (right hand side) component. * But any property required by the decorated component must be satisfied by the injected property. */ export type Shared<InjectedProps, DecorationTargetProps> = { [P in Extract< keyof InjectedProps, keyof DecorationTargetProps >]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never } // Infers prop type from component C export type GetProps<C> = C extends ComponentType<infer P> ? C extends ComponentClass<P> ? ClassAttributes<InstanceType<C>> & P : P : never // Applies LibraryManagedAttributes (proper handling of defaultProps // and propTypes), as well as defines WrappedComponent. export type ConnectedComponent< C extends ComponentType<any>, P > = ComponentType<P> & NonReactStatics<C> & { WrappedComponent: C } // Injects props and removes them from the prop requirements. // Will not pass through the injected props if they are passed in during // render. Also adds new prop requirements from TNeedsProps. // Uses distributive omit to preserve discriminated unions part of original prop type export type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> = < C extends ComponentType<Matching<TInjectedProps, GetProps<C>>> >( component: C ) => ConnectedComponent< C, DistributiveOmit<GetProps<C>, keyof Shared<TInjectedProps, GetProps<C>>> & TNeedsProps > // Injects props and removes them from the prop requirements. // Will not pass through the injected props if they are passed in during // render. export type InferableComponentEnhancer<TInjectedProps> = InferableComponentEnhancerWithProps<TInjectedProps, {}> export type InferThunkActionCreatorType< TActionCreator extends (...args: any[]) => any > = TActionCreator extends ( ...args: infer TParams ) => (...args: any[]) => infer TReturn ? (...args: TParams) => TReturn : TActionCreator export type HandleThunkActionCreator<TActionCreator> = TActionCreator extends ( ...args: any[] ) => any ? InferThunkActionCreatorType<TActionCreator> : TActionCreator // redux-thunk middleware returns thunk's return value from dispatch call // https://github.com/reduxjs/redux-thunk#composition export type ResolveThunks<TDispatchProps> = TDispatchProps extends { [key: string]: any } ? { [C in keyof TDispatchProps]: HandleThunkActionCreator<TDispatchProps[C]> } : TDispatchProps // the conditional type is to support TypeScript 3.0, which does not support mapping over tuples and arrays; // once the typings are updated to at least TypeScript 3.1, a simple mapped type can replace this mess export type ResolveArrayThunks<TDispatchProps extends ReadonlyArray<any>> = TDispatchProps extends [ infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, infer A8, infer A9 ] ? [ HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3>, HandleThunkActionCreator<A4>, HandleThunkActionCreator<A5>, HandleThunkActionCreator<A6>, HandleThunkActionCreator<A7>, HandleThunkActionCreator<A8>, HandleThunkActionCreator<A9> ] : TDispatchProps extends [ infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, infer A8 ] ? [ HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3>, HandleThunkActionCreator<A4>, HandleThunkActionCreator<A5>, HandleThunkActionCreator<A6>, HandleThunkActionCreator<A7>, HandleThunkActionCreator<A8> ] : TDispatchProps extends [ infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7 ] ? [ HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3>, HandleThunkActionCreator<A4>, HandleThunkActionCreator<A5>, HandleThunkActionCreator<A6>, HandleThunkActionCreator<A7> ] : TDispatchProps extends [ infer A1, infer A2, infer A3, infer A4, infer A5, infer A6 ] ? [ HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3>, HandleThunkActionCreator<A4>, HandleThunkActionCreator<A5>, HandleThunkActionCreator<A6> ] : TDispatchProps extends [infer A1, infer A2, infer A3, infer A4, infer A5] ? [ HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3>, HandleThunkActionCreator<A4>, HandleThunkActionCreator<A5> ] : TDispatchProps extends [infer A1, infer A2, infer A3, infer A4] ? [ HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3>, HandleThunkActionCreator<A4> ] : TDispatchProps extends [infer A1, infer A2, infer A3] ? [ HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3> ] : TDispatchProps extends [infer A1, infer A2] ? [HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>] : TDispatchProps extends [infer A1] ? [HandleThunkActionCreator<A1>] : TDispatchProps extends Array<infer A> ? Array<HandleThunkActionCreator<A>> : TDispatchProps extends ReadonlyArray<infer A> ? ReadonlyArray<HandleThunkActionCreator<A>> : never /** * This interface allows you to easily create a hook that is properly typed for your * store's root state. * * @example * * interface RootState { * property: string; * } * * const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector; */ export interface TypedUseSelectorHook<TState> { <TSelected>( selector: (state: TState) => TSelected, equalityFn?: EqualityFn<TSelected> ): TSelected }