Home > OS >  How to add interface to check each prop type correctly?
How to add interface to check each prop type correctly?

Time:03-15

Working with Typescript I am trying to have an interface with each property inside my object of marks. Currently, I am using "any" but this is not the smartest to do. What is the advice to do here? Thanks in advance for the help and tips.

I am sharing my error and code underneath. Trying to become better in TS so would be great for know how I can solve this.

Error:

Type '{ highlight: ({ children }: { children: any; }) => Element; buttonLink: ({ text, value }: any) => Element; internalLink: ({ text, value }: any) => Element; link: ({ children, value }: any) => Element; }' is not assignable to type 'marksProps'.
  Object literal may only specify known properties, and 'highlight' does not exist in type 'marksProps'.ts(2322)

Code:

import Link from "next/link";

import { Warning } from "phosphor-react";

interface marksProps {
  children?: any;
}

export const marks: marksProps = {
  highlight: ({ children }) => <mark>{children}</mark>,

  buttonLink: ({ text, value }: any) => {
    const title = value?.colors?.title;
    const path = value?.path;

    /* prettier-ignore */
    const Theme : { [key: string]: any } = {
      neon      : "bg-neon text-navyBlue border-navyBlue hover:bg-offWhite",
      clear     : "bg-transparent text-white border-white hover:bg-offWhite hover:text-navyBlue",
      bubblegum : "bg-bubblegum text-navyBlue border-navyBlue hover:bg-offWhite hover:text-navyBlue",
      sand      : "bg-sand text-navyBlue border-navyBlue hover:bg-offWhite hover:text-navyBlue",
      navyBlue  : "bg-navyBlue text-white border-white hover:bg-offWhite hover:text-navyBlue"
    };

    const Button = () => (
      <>
        {path ? (
          <Link href={value.path}>
            <a
              className={`inline-flex items-center px-4 py-2 mt-6 text-xs font-bold text-center uppercase duration-300 ease-in-out border-2 rounded-full ${Theme[title]}`}
            >
              {text}
            </a>
          </Link>
        ) : (
          <div className="block mt-4">
            <p className="flex gap-2 text-sm font-bold text-sand place-items-center">
              <Warning size={24} color="#ffd662" weight="duotone" />
              <span>Page reference URL is required.</span>
            </p>

            <button
              disabled
              className="inline-flex items-center px-4 py-2 mt-3 text-xs font-bold text-center uppercase duration-300 ease-in-out border-2 rounded-full disabled:bg-gray-700 disabled:opacity-30"
            >
              {text}
            </button>
          </div>
        )}
      </>
    );

    return <Button />;
  },

  internalLink: ({ text, value }: any) => {
    return (
      <Link href={value.path}>
        <a className="underline cursor-pointer text-bubblegum">{text}</a>
      </Link>
    );
  },

  link: ({ children, value }: any) => {
    const blank = value.blank;

    return blank ? (
      <a
        className="underline cursor-pointer text-bubblegum"
        href={value.href}
        rel="noreferrer"
        target="_blank"
      >
        {children}
      </a>
    ) : (
      <a
        className="underline cursor-pointer text-bubblegum"
        href={value.href}
        rel="noreferrer"
      >
        {children}
      </a>
    );
  },
};

CodePudding user response:

You need to change the children property to be an array of React.ReactNode. After that, you also need to assign your type, marksProps, to the props of the marks arrow function props and not the constant.

import React from "react";
import { Warning } from "phosphor-react";

interface marksProps {
  children?: React.ReactNode[];
}

export const marks = {
  highlight: ({ children }: marksProps) => <mark>{children}</mark>,

  buttonLink: ({ text, value }: any) => {
    const title = value?.colors?.title;
    const path = value?.path;

    /* prettier-ignore */
    const Theme : { [key: string]: any } = {
      neon      : "bg-neon text-navyBlue border-navyBlue hover:bg-offWhite",
      clear     : "bg-transparent text-white border-white hover:bg-offWhite hover:text-navyBlue",
      bubblegum : "bg-bubblegum text-navyBlue border-navyBlue hover:bg-offWhite hover:text-navyBlue",
      sand      : "bg-sand text-navyBlue border-navyBlue hover:bg-offWhite hover:text-navyBlue",
      navyBlue  : "bg-navyBlue text-white border-white hover:bg-offWhite hover:text-navyBlue"
    };

    const Button = () => (
      <>
        {path ? (
          <Link href={value.path}>
            <a
              className={`inline-flex items-center px-4 py-2 mt-6 text-xs font-bold text-center uppercase duration-300 ease-in-out border-2 rounded-full ${Theme[title]}`}
            >
              {text}
            </a>
          </Link>
        ) : (
          <div className="block mt-4">
            <p className="flex gap-2 text-sm font-bold text-sand place-items-center">
              <Warning size={24} color="#ffd662" weight="duotone" />
              <span>Page reference URL is required.</span>
            </p>

            <button
              disabled
              className="inline-flex items-center px-4 py-2 mt-3 text-xs font-bold text-center uppercase duration-300 ease-in-out border-2 rounded-full disabled:bg-gray-700 disabled:opacity-30"
            >
              {text}
            </button>
          </div>
        )}
      </>
    );

    return <Button />;
  },

  internalLink: ({ text, value }: any) => {
    return (
      <Link href={value.path}>
        <a className="underline cursor-pointer text-bubblegum">{text}</a>
      </Link>
    );
  },

  link: ({ children, value }: any) => {
    const blank = value.blank;

    return blank ? (
      <a
        className="underline cursor-pointer text-bubblegum"
        href={value.href}
        rel="noreferrer"
        target="_blank"
      >
        {children}
      </a>
    ) : (
      <a
        className="underline cursor-pointer text-bubblegum"
        href={value.href}
        rel="noreferrer"
      >
        {children}
      </a>
    );
  },
};

TypeScript Playground Link

  • Related