Skip to content

Better typings for connect #160

Description

@yannick-cw

Hey,
using the current connect in typescript seems to give not as much type safety as possible. I came ob with these types/changes to make it more safe for us, as we had it more than once that we actually broke things without these types.

export const safeConnect = <T, S, K, I>(
  pickFromState: (keyof K) & (keyof I) & string | Array<(keyof K) & (keyof I) & string> | StateMapper<T, K, I>,
  actions?: PropsActions<I, K> | Array<PropsActions<I, K>> | SafeActionCreator<K, I>,
): ((Child: ComponentConstructor<T & I, S> | AnyComponent<T & I, S>) => ComponentConstructor<T, S>) =>
  connect<T, S, K, I>(
    pickFromState,
    Array.isArray(actions) ? actions.reduce((prev, current) => ({ ...prev, ...current }), {}) : actions,
  );

export type SafeActionCreator<K, I> = (store: Store<K>) => PropsActions<I, K>;

type PropsActions<I extends Record<string, any>, K> = {
  [P in keyof Partial<I>]: I[P] extends ((...args: any[]) => void)
    ? (s: State, ...a: Parameters<I[P]>) => Promise<Partial<K>> | Partial<K> | void
    : never
};

This ensures a few things, maybe an example shows that better:

export interface Store {
  counter: number,
}

export const counterAction = {
  setCounter: (_: State, n: number) => ({ counter: n }),
};

export interface ComponentConnectedProps {
  counter: number;
  setCounter: (count: number) => void
}

// usage
export const ConnectedComponent = safeConnect<{}, {}, Store, ComponentConnectedProps>(
  ['counter'], // or 'counter'
  [counterAction], // or counterAction
)(Component);
  1. pickFromState parameter from safeConnect
  • needs to be a key of the Store and the ComponentConnectedProps
  1. actions parameter from safeConnect
  • key of the action object needs to be in the ComponentConnectedProps
  • function parameter (without the State) needs to match the one in ComponentConnectedProps
  • return type of the action function needs to be Partial of the state

The one thing it can not ensure, is that all of the items from ComponentConnectedProps are there.

Is there interest to get some version of this upstream?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions