TypeScript构建报错:模板字面量表达式类型为string | undefined问题排查
解决TypeScript模板字面量类型报错问题
报错信息
17:60 Error: Invalid type "string | undefined" of template literal expression.
相关组件代码
HiglightedCustomers组件
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> ); };
Button组件
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}) => { // Returner svart tekst på bakgrunner som krever svart tekst, ellers svart tekst 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>} </> ); };
问题根源
报错出在Button组件的buttonStyle模板字面量中。TypeScript推断textColor函数的返回值类型为string | undefined,虽然实际逻辑里该函数一定会返回字符串,但TypeScript无法自动识别这一点。当在模板字面量中使用textColor({ variant }) || ''时,TypeScript认为表达式可能是undefined,触发类型错误。
解决方案
方案1:明确指定textColor的返回类型
给textColor函数添加string返回类型,消除TypeScript的不确定推断:
const textColor = ({variant}:{variant: Variant}): string => { if(variant === "bg-primary-light-pink"){ return "text-black " } else { return "text-white group-hover:text-black" } }
方案2:移除冗余的|| ''
由于textColor函数本身已经确保返回字符串,不需要额外的空字符串兜底,可以直接简化模板字面量:
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`
额外优化:优化customerList的类型处理
在HiglightedCustomers组件中,customers被定义为非空数组(Kunder[]),所以customers?.map不会返回undefined,可以去掉冗余的类型断言和判断:
// 替换原来的customerList定义 const customerList = customers.map((customer) => <CustomerTemplate key={customer.id} customer={customer} />); // 渲染时直接使用 {customerList}
内容的提问来源于stack exchange,提问作者sam_vimes
相关产品推荐
相关产品推荐

