Jason McFarlane
Jason McFarlane

Reputation: 2175

Typescript react context + Type '{}' has no call signatures

I have created a Notification Toast service which seems to be working except for some typescript errors surrounding the ToastContext.

Calling the toast on any page I import my useToast() hook which connects to the contextProvider. The typescript error occurs with the toast(...) function. The error I receive is

Error This expression is not callable. Type '{}' has no call signatures.

Toast Hook

<button
    onClick={() => {
        return toast({
            title: "I am toasty"
        });
    }}
>Toast Me</button>

Context & useContext hook

export const ToastContext = createContext({});

export function useToast() {
  return useContext(ToastContext);
}

Here is a codesandbox to the current code https://codesandbox.io/s/dazzling-spence-clehl.

I have tried typing my createContext with

interface ContextType {
   toasts: []
   toast: () => void
}

export const ToastContext = createContext<ContextType | {}>({});

Upvotes: 3

Views: 4389

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53874

Your context value is a function, while you initialize the context with an empty object (why?), so on static type evaluation, calling toast() is a try to emit a function on an object ('{}' has no call signatures).

Fix your initialization according to its usage:

// toast is a function
<ToastContext.Provider value={toast}>{children}</ToastContext.Provider>

export const ToastContext = createContext((payload: any) => {});

Or, I guess your initial idea was trying to do something like:

// import ToastProps
interface ContextType {
  toasts: [] | ToastProps[];
  toast: (payload: any) => void;
}

export const ToastContext = createContext<ContextType>({
  toast: () => {},
  toasts: []
});

// Initilization
const { toast, toasts } = useToasts();

// Pass ContextType
<ToastContext.Provider value={{toast, toasts}}>{children}</ToastContext.Provider>

// Context usage
const { toast } = useToast();
toast(); // is a function, GOOD

Where ContextType matches useToast return value and createContext (Try reuse ContextType with useToast return value).

Edit Context Types Fix

Upvotes: 2

Related Questions