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

扩展forwardRef组件(如ListItem)时的TypeScript错误排查

解决forwardRef组件挂载静态属性的TypeScript类型错误

问题根源在于:forwardRef返回的组件实例在初始化时并没有Placeholder属性,但你直接给ListItem指定了包含Placeholder的ListItemComponent类型,TypeScript会在变量声明时就做类型校验,这时候属性还没加上,自然报错。

下面是几种可行的解决办法:

方法一:分步创建,最后断言类型

先创建不带类型的forwardRef组件,添加静态属性后再断言为目标类型:

import { forwardRef, FunctionComponent, ForwardRefExoticComponent, RefAttributes } from 'react';

type Props = {/* 你的Props定义 */};

type ListItemComponent = ForwardRefExoticComponent<Props & RefAttributes<HTMLDivElement>> & {
  Placeholder: typeof ListItemPlaceholder;
};

// 先不指定类型,创建基础组件
const ListItem = forwardRef<HTMLDivElement, Props>((props, ref) => {
  // 组件内部逻辑
  return <div ref={ref} />;
});

const ListItemPlaceholder: FunctionComponent = () => {
  return <div />;
};

// 挂载静态属性
ListItem.Placeholder = ListItemPlaceholder;

// 断言类型后导出
export const TypedListItem = ListItem as ListItemComponent;

方法二:用Object.assign一次性构建符合类型的组件

通过Object.assign把forwardRef组件和静态属性合并,直接满足类型要求,无需额外断言:

import { forwardRef, FunctionComponent, ForwardRefExoticComponent, RefAttributes } from 'react';

type Props = {/* 你的Props定义 */};

type ListItemComponent = ForwardRefExoticComponent<Props & RefAttributes<HTMLDivElement>> & {
  Placeholder: typeof ListItemPlaceholder;
};

const ListItemPlaceholder: FunctionComponent = () => {
  return <div />;
};

export const ListItem: ListItemComponent = Object.assign(
  forwardRef<HTMLDivElement, Props>((props, ref) => {
    // 组件内部逻辑
    return <div ref={ref} />;
  }),
  { Placeholder: ListItemPlaceholder }
);

方法三:修改类型定义(不推荐,除非允许属性可选)

如果业务上允许Placeholder属性存在或不存在,可以把它设为可选属性,这样初始化时的类型校验就能通过:

import { forwardRef, FunctionComponent, ForwardRefExoticComponent, RefAttributes } from 'react';

type Props = {/* 你的Props定义 */};

// 将Placeholder设为可选属性
type ListItemComponent = ForwardRefExoticComponent<Props & RefAttributes<HTMLDivElement>> & {
  Placeholder?: typeof ListItemPlaceholder;
};

export const ListItem: ListItemComponent = forwardRef<HTMLDivElement, Props>((props, ref) => {
  // 组件内部逻辑
  return <div ref={ref} />;
});

const ListItemPlaceholder: FunctionComponent = () => {
  return <div />;
};

ListItem.Placeholder = ListItemPlaceholder;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:22:22