I am facing an issue with a simple component that loops out buttons. During the TypeScript build, I encountered an error when calling this loop:
17:60 Error: Invalid type "string | undefined" of template literal expression.
In my JSX return, I call the function like this:
{customerList && customerList as JSX.Element[]}
There are no template literals in the file where I loop out buttons, so I believe the problem lies elsewhere. Here is the full file content (excluding imports and exports):
const HiglightedCustomers = ({ customers, title }: { customers: Kunder[], title : string }) => {
const CustomerTemplate = ({customer}:{customer: Kunder}) => {
const {url, name} = customer
return <div className="p-2">
<Button href={url || "#"} externalLink={true} variant="bg-primary-light-pink">{name}</Button>
</div>
}
const customerList = customers?.map((customer) => <CustomerTemplate key={customer.id} customer={customer} />);
return (
<div className="border bg-red-500 ">
<h2 className="text-3xl text-center">{title}</h2>
<div className="flex max-w-3xl pt-3 flex-wrap justify-center">
{customerList && customerList as JSX.Element[]}
</div>
</div>
);
};
Inside my component, I utilize template literals in a way that appears safe to me. I have default values for props and functions that handle undefined template literals without issues.
This is my button file:
import { z } from 'zod';
import Link from 'next/link';
import { BgColorVariants } from '@/lib/commonTypes';
type Variant = z.infer<typeof BgColorVariants>;
const ButtonSchema = z.object({
variant: BgColorVariants.optional(),
children: z.string(),
link: z.boolean().optional(),
externalLink: z.boolean().optional(),
href: z.string().optional(),
});
type ButtonProps = z.infer<typeof ButtonSchema>;
const Button = ({ variant = 'bg-black', externalLink = false, href, children,...rest }: ButtonProps) => {
const textColor = ({variant}:{variant: Variant}) => {
// Return black text on backgrounds that require it, otherwise white text
if(variant === "bg-primary-light-pink"){
return "text-black "
}
else {
return "text-white group-hover:text-black"
}
}
const ButtonContent = () => {
const buttonStyle = `relative z-10 inline-flex items-center justify-center h-full w-full rounded py-2 px-3 ${textColor({ variant }) || ''} ${variant} border border-black group-hover:bg-primary-pink group-hover:border-black group-hover:border-w`
const shadowBox = "absolute top-[0.15em] left-[0.15em] h-full w-full group-hover:bg-black bg-transparent rounded py-2 px-3 z-0 group-hover:border-black group-hover:border "
return (
<div className="relative inline-block group">
<div className={shadowBox}></div>
<div className={buttonStyle}>{children}</div>
</div>
)
};
return (
<>
{href && !externalLink && <Link href={href}><ButtonContent /></Link> }
{href && externalLink && <a href={href} rel="external nofollow"><ButtonContent /></a> }
{!href && <button ><ButtonContent /></button>}
</>
);
};
I have been struggling to debug this issue for days and any suggestions on how to resolve it would be greatly appreciated.