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就能解决:- 导入官方提供的类型
import { Virtuoso, ListProps, ItemProps } from 'react-virtuoso';- 修改自定义组件的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
相关产品推荐
相关产品推荐

