Bill
Bill

Reputation: 19238

React Context API with Typescript Generic

type ContextProps<T = object> = {
  store: T,
  updateStore: React.Dispatch<T>
};

export default React.createContext<Partial<ContextProps>>({}); // is there any way to pass the generic? so store can correct type

export function Provider<T, K>(props: T & { store: K }) {
  const [globalState, updateStore] = React.useState(props.store);
  const value = React.useMemo(
    () => ({
      store: globalState,
      updateStore,
    }),
    [globalState],
  );

  return <StateMachineContext.Provider value={value} {...props} />;
}

Is there any way to pass generic into Context, so value can have the correct type?

Upvotes: 4

Views: 3491

Answers (1)

Jerryc
Jerryc

Reputation: 310

pass the type when creating the context, remember to create it outside the components.

type ContextProps<T = object> = {
  store: T,
  updateStore: React.Dispatch<T>
};

function createGenericContext<T extends object> () {
  return React.createContext<Partial<ContextProps<T>>>({}); 
}

const StateMachineContext = createGenericContext<{type: 'a'}>();
// or just
const StateMachineContext = React.createContext<Partial<ContextProps<{type: 'a'}>>>({});

export function Provider<T, K>(props: T & { store: K }) {
  const [globalState, updateStore] = React.useState(props.store);
  const value = React.useMemo(
    () => ({
      store: globalState,
      updateStore,
    }),
    [globalState],
  );

  return <StateMachineContext.Provider value={value} {...props} />;
}

Upvotes: 6

Related Questions