You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为映射元素声明类型?解决HeadlessUI MenuItem className报错

HeadlessUI MenuItem 映射时 TypeScript className 类型报错解决

问题描述

使用HeadlessUI的MenuItem组件做数组映射时,给MenuItem添加className属性触发TypeScript报错,提示该属性不存在于组件的类型定义中。尝试自定义MenuItemProps接口未解决问题。

报错信息

Type '{ children: Element; key: string; className: string; }' is not assignable to type 'IntrinsicAttributes & CleanProps<ExoticComponent<{ children?: ReactNode; }>, "disabled" | ItemPropsWeControl> & OurProps<...> & { ...; } & { ...; }'.

Property 'className' does not exist on type 'IntrinsicAttributes & CleanProps<ExoticComponent<{ children?: ReactNode; }>, "disabled" | ItemPropsWeControl> & OurProps<...> & { ...; } & { ...; }'.ts(2322)

原代码

import React, { ReactNode } from 'react'
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react'

const links = [
    {href: '/home', label: 'Home'},
    {href: '/Test', label: 'Test'},
    {href: '/settings', label: 'Settings'}
]

interface MenuItemProps{
    children: any
    className?: any
    key: any
}

export const MyComponent = () => {
    return(
        <Menu>
            <MenuButton className='data-[active]:bg-blue-500'></MenuButton>
            <MenuItems anchor='bottom'>
                {links.map((link) => (
                    <MenuItem key={link.href} className='block data-[focus]:bg-blue-500'>
                        <a href={link.href}>{link.label}</a>
                    </MenuItem>
                ))}
            </MenuItems>
        </Menu>
    )
}

解决方法

HeadlessUI的MenuItem组件本身不支持直接传入className属性,正确的做法是将样式应用到它内部的元素上,或通过render prop模式利用组件提供的状态动态设置样式:

方法1:将 className 转移到内部元素

直接把样式加到MenuItem包裹的<a>标签上,同时可保留HeadlessUI的状态驱动data属性(如data-[focus]):

export const MyComponent = () => {
    return(
        <Menu>
            <MenuButton className='data-[active]:bg-blue-500'></MenuButton>
            <MenuItems anchor='bottom'>
                {links.map((link) => (
                    <MenuItem key={link.href}>
                        <a 
                          href={link.href} 
                          className='block data-[focus]:bg-blue-500'
                        >
                            {link.label}
                        </a>
                    </MenuItem>
                ))}
            </MenuItems>
        </Menu>
    )
}

方法2:使用 render prop 获取状态动态设样式

通过MenuItem的render prop形式拿到组件的状态(如active),自定义样式逻辑:

export const MyComponent = () => {
    return(
        <Menu>
            <MenuButton className='data-[active]:bg-blue-500'></MenuButton>
            <MenuItems anchor='bottom'>
                {links.map((link) => (
                    <MenuItem key={link.href} as={React.Fragment}>
                        {({ active }) => (
                            <a 
                              href={link.href} 
                              className={`block ${active ? 'bg-blue-500' : ''}`}
                            >
                                {link.label}
                            </a>
                        )}
                    </MenuItem>
                ))}
            </MenuItems>
        </Menu>
    )
}

为什么自定义接口没用?

你自定义的MenuItemProps并没有关联到HeadlessUI提供的MenuItem组件类型上,组件的props类型由库本身定义,自定义接口无法覆盖或扩展它的类型约束。


内容的提问来源于stack exchange,提问作者giveearholdtongue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:41:13