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

React Virtuoso自定义ul/li组件的TypeScript类型错误解决方法

解决React Virtuoso自定义
    /
  • 组件的TypeScript类型错误

问题描述

我用React Virtuoso构建虚拟列表,默认渲染的是嵌套

结构,现在想改成
    嵌套
  • 的结构并添加样式,写了自定义的Item和List组件后功能正常,但出现TypeScript类型错误。官方示例用emotion的styled元素,不清楚对应的类型定义该怎么写。

    当前代码

    import React from 'react';
    import { Virtuoso } from 'react-virtuoso';
    
    const Item = React.forwardRef<HTMLLIElement, { children: React.ReactNode }>(
      (props, ref) => {
        return (
          <li className="border-r border-neutral-20" {...props} ref={ref}>
            {props.children}
          </li>
        );
      }
    );
    
    const List = React.forwardRef<HTMLUListElement, { children: React.ReactNode }>(
      (props, ref) => {
        return (
          <ul className="list-none divide-y divide-neutral-20" {...props} ref={ref}>
            {props.children}
          </ul>
        );
      }
    );
    
    const MyListComponent: React.FC = () => {
      return (
        <Virtuoso
          // 其他配置项
          components={{ List, Item }}
          itemContent={(index: number) => {
            // 渲染每个项的内容
          }}
        />
      );
    };
    

    错误信息

    Type 'ForwardRefExoticComponent<{ children: ReactNode; } & RefAttributes<HTMLUListElement>>' is not assignable to type 'ComponentType<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }> | undefined'.
      Type 'ForwardRefExoticComponent<{ children: ReactNode; } & RefAttributes<HTMLUListElement>>' is not assignable to type 'FunctionComponent<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }>'.
        Types of property 'propTypes' are incompatible.
          Type 'WeakValidationMap<{ children: ReactNode; } & RefAttributes<HTMLUListElement>> | undefined' is not assignable to type 'WeakValidationMap<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }> | undefined'.
            Type 'WeakValidationMap<{ children: ReactNode; } & RefAttributes<HTMLUListElement>>' is not assignable to type 'WeakValidationMap<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, "ref" | ... 1 more ... | "style"> & { ...; } & { ...; }>'.
              Types of property 'ref' are incompatible.
                Type 'Validator<Ref<HTMLUListElement> | undefined> | undefined' is not assignable to type 'Validator<((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined> | undefined'.
                  Type 'Validator<Ref<HTMLUListElement> | undefined>' is not assignable to type 'Validator<((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined>'.
                    Type 'Ref<HTMLUListElement> | undefined' is not assignable to type '((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
                      Type '(instance: HTMLUListElement | null) => void' is not assignable to type '((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
                        Type '(instance: HTMLUListElement | null) => void' is not assignable to type '(instance: HTMLDivElement | null) => void'.
                          Types of parameters 'instance' and 'instance' are incompatible.
                            Type 'HTMLDivElement | null' is not assignable to type 'HTMLUListElement | null'.
                              Type 'HTMLDivElement' is missing the following properties from type 'HTMLUListElement': compact, typets(2322)
    

    解决方案

    问题根源是自定义组件的props和ref类型没有匹配React Virtuoso官方要求的类型,直接用官方导出的ListProps和ItemProps就能解决:

    1. 导入官方提供的类型
    import { Virtuoso, ListProps, ItemProps } from 'react-virtuoso';
    
    1. 修改自定义组件的props类型,替换成官方的ListProps和ItemProps
    const Item = React.forwardRef<HTMLLIElement, ItemProps>(
      (props, ref) => {
        return (
          <li className="border-r border-neutral-20" {...props} ref={ref}>
            {props.children}
          </li>
        );
      }
    );
    
    const List = React.forwardRef<HTMLUListElement, ListProps>(
      (props, ref) => {
        return (
          <ul className="list-none divide-y divide-neutral-20" {...props} ref={ref}>
            {props.children}
          </ul>
        );
      }
    );
    

    这样修改后,TypeScript就能正确识别组件类型,因为ListProps和ItemProps已经包含了Virtuoso传递的所有必要属性(比如样式、ref等),同时允许我们指定对应的HTML元素类型(HTMLUListElement/HTMLLIElement),完美兼容官方的类型要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 17:01:05