React+TypeScript中CSS Modules多样式组件的TypeScript报错问题
问题:CSS Modules动态类名结合TypeScript报错
我开发了可复用的NavbarList组件,分别在NavbarDesktop和SideDrawer中使用,想通过传递prefix属性区分不同父组件下的样式——用prefix拼接CSS Modules的类名,但遇到了TypeScript错误。
代码示例
// NavbarDesktop 中调用组件 <NavbarList prefix="header-navbar"/> // SideDrawer 中调用组件 <NavbarList closeMenu={close} prefix="sidedrawer-navbar" /> // NavbarList 组件实现 import { NavLink } from 'react-router-dom'; import NavbarListScss from './_NavbarList.module.scss'; type NavbarListProps = { closeMenu?: () => void; prefix: string; } const NavbarList = ({closeMenu, prefix} : NavbarListProps) => { const listSelector = `${prefix}__list`; const itemSelector = `${prefix}__item`; const linkSelector = `${prefix}__link`; return ( <ul className={`${NavbarListScss[${listSelector}]}`}> {/* 组件其余内容 */} </ul> ) }
报错信息
'...' expected.ts(1005) Spread types may only be created from object types.ts(2698) const listSelector: string
问题分析与修复
报错的根源是语法错误:你在NavbarListScss[${listSelector}]里错误嵌套了模板字符串语法,方括号内直接用变量名即可,不需要额外的${}包裹。TypeScript把这个错误解析成了类似扩展运算符的语法问题,所以给出了看似不相关的错误提示。
第一步:修正语法错误
把有问题的行改成:
<ul className={NavbarListScss[listSelector]}>
第二步:解决TypeScript类型检查问题
此时还会有类型错误,因为listSelector是string类型,TypeScript无法确认它是否是CSS Modules导出的合法类名。可以用以下两种方式处理:
- 限定prefix的可选值
把prefix的类型改成联合类型,确保只能传入预定义的前缀:
type NavbarListProps = { closeMenu?: () => void; prefix: 'header-navbar' | 'sidedrawer-navbar'; }
然后给拼接后的变量添加类型断言,告诉TypeScript这是合法的类名键:
const listSelector = `${prefix}__list` as keyof typeof NavbarListScss;
- 直接使用类型断言
如果不想限制prefix的取值,直接给变量断言为CSS Modules的键类型:
const listSelector = `${prefix}__list` as keyof typeof NavbarListScss; const itemSelector = `${prefix}__item` as keyof typeof NavbarListScss; const linkSelector = `${prefix}__link` as keyof typeof NavbarListScss;
这样就能同时解决语法错误和TypeScript类型检查的问题。
内容的提问来源于stack exchange,提问作者Ingeborg De Smedt
相关产品推荐
相关产品推荐

