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>
);
},
};