How do you access and declare the types of a react component?

941 Views Asked by At

Here I have a component that should print a toast adding an icon to the content depending on the type of the toast:

import * as React from 'react';
import { toast }  from 'react-toastify';
import { FaInfo, FaCheck, FaExclamationTriangle, FaBug, FaExclamationCircle } from 'react-icons/fa';
import { TypeOptions, ToastContent, Toast } from 'react-toastify/dist/types/index';

interface IToast {
  message: ToastContent;
  type: TypeOptions;
}
    
const displayIcon = ({ type }: IToast) => {
          switch (type) {
            case 'success':
              return <FaCheck />;
            case 'info':
              return <FaInfo />;
            case 'error':
              return <FaExclamationCircle />;
            case 'warning':
              return <FaExclamationTriangle />;
            default:
              return <FaBug />;
          }
        };
    
const myToast = ({ type, message }: IToast): Toast => {
  return toast[type](
    <div>
      <div>
        {displayIcon(type)}
      </div>
      <div>{message}</div>
    </div>,
  );
};

export default myToast;

Im rendering myToast on another component by doing:

const notify = React.useCallback((message: ToastContent, type: ToastOptions) => {
lomplayToast({ message, type });
  }, []);

The components already work and they do what they are intended to. But Im not able to make a good type declaration. The Toast interface comes with several interface and type declarations. One of them is ToastOptions type which the displayIcon is able to retrieve. My questions:

  1. Why does the toast[type] attribute throws "Property 'default' does not exist on type '{ (message: ToastContent, type: TypeOptions | undefined): ReactText;..."? Where is this default property coming from?
1

There are 1 best solutions below

2
On

There are 2 places where types could be declared on a function.

  1. You can declare types for the props.
  2. You can declare a type for what the function returns, a ReturnType.

it looks like this

const yourFunction = (props: PropType): ReturnType => { ... }

You declared your ToastProps as a ReturnType.

Do this:

const myToast = ({ type, message }: ToastProps) => { ... }

instead of:

const myToast = ({ type, message }): ToastProps => { ... }

It's a very subtle change.


Note: This counts for any function, but React has their own types for functions. You can type a React component function like this:

const myToast: React.FunctionComponent<ToastProps> = ({ message, type }) => { ... }

Behind the scenes, it will create something like this:

const myToast = (props: ToastProps): JSX.Element => { ... }
// It does some more stuff, but I simplified it for this example.