Gurkiran Singh
Gurkiran Singh

Reputation: 319

why I am getting never type in useReducer in TS?

I am making a reducer state of three values, conversations- intially empty array with the described properties, messages - intially empty array with described properties and activeConversation string. But I keep on getting typescript never errors. I don't understand. Can someone please resolve this for me ?

import { useReducer, useContext, createContext, FunctionComponent } from 'react';

export interface IConversations {
  conversationId: string;
  latestMessage: {
    latestMessageText: string;
    createdAt: string;
  };
  recipientUser: {
    fullName: string;
    email: string;
    online: boolean;
    recipientUserId: string;
    profileImg?: string;
  };
}

export interface IMessages {
  _id: string;
  author: string;
  text: string;
  createdAt: string;
  updatedAt: string;
}

interface IMessageReducer {
  conversations: IConversations[];
  messages: IMessages[];
  activeConversation: string;
}

type Action =
  | { type: 'UPLOAD_PROFILE'; profileImg: string }

type Dispatch = (action: Action) => void;

interface IUseMessage {
  messageState: IMessageReducer;
  dispatchMessageContext: Dispatch;
}

const messageReducer = (state: IMessageReducer, action: Action) => {
  switch (action.type) {
    default:
      return state;
  }
};

const MessageContext = createContext({
  conversations: [],
  messages: [],
  activeConversations: ''
});

const MessageProvider: FunctionComponent = ({ children }): JSX.Element => {
  const [messageState, dispatchMessageContext] = useReducer(messageReducer, {
    conversations: [],
    messages: [],
    activeConversations: ''
  });

  return <MessageContext.Provider value={{ messageState, dispatchMessageContext }}>{children}</MessageContext.Provider>
}

const useMessage = (): IMessageReducer => {
  const context = useContext(MessageContext);
  if (context === undefined) {
    throw new Error('useMessage must be used within a MessageProvider');
  }
  return context;
}

export { MessageProvider, useMessage }

Upvotes: 1

Views: 556

Answers (1)

Apostolos
Apostolos

Reputation: 10463

You need to use typescript generics here and "force" the react context to understand the types it is using.

So instead of

const MessageContext = createContext({

it should be

const MessageContext = createContext<IMessageReducer>({

and

const [messageState, dispatchMessageContext] = useReducer(messageReducer, {

should become

const [messageState, dispatchMessageContext] = useReducer<
Reducer<IMessageReducer, any>(messageReducer, {

Upvotes: 1

Related Questions