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

React.memo组件类型差异:MemoExoticComponent与NamedExoticComponent区别

解答

1. 类型差异与报错的原因

  • SimpleMemo正常的原因:Simple组件的_props没有显式声明类型,TypeScript会默认推断为any。React.memo包装这个组件后,会保留props的any类型——any类型允许任意属性传递,所以style不会触发类型检查错误,对应的类型就是MemoExoticComponent<(_props: any) => JSX.Element>。
  • SimpleMemo2报错的原因:匿名组件的_props没有显式声明类型,但你给函数返回值标注了JSX.Element,TypeScript会默认把_props推断为object类型。但TypeScript中的object是一个宽泛的类型,仅表示“非原始类型”,不包含任何具体属性定义。所以当你传递style属性时,TypeScript会检测到该属性不在object的属性集中,从而抛出错误。同时因为是匿名函数,React.memo返回的类型就变成了NamedExoticComponent<object>。

2. MemoExoticComponent与NamedExoticComponent的区别

  • MemoExoticComponent:是React.memo包装有名称的组件(比如Simple这种具名函数组件)后返回的类型,它会完整保留原组件的props类型信息,本质是一个专门用于记忆化渲染的组件包装器。
  • NamedExoticComponent:当直接给React.memo传递匿名函数组件时,TypeScript会将其推断为这个类型。它的props类型默认会被推断为object(如果没有显式声明),相比MemoExoticComponent,它丢失了原组件更精确的props类型约束。

3. 让匿名函数版React.memo正常使用的方法

核心是给匿名组件的props显式声明正确的类型,有几种方式:

方式一:声明HTML元素属性类型

如果组件要接收style这类原生HTML元素的属性,可以直接用React.HTMLAttributes:

const SimpleMemo2 = React.memo((_props: React.HTMLAttributes<HTMLDivElement>): JSX.Element => {
    return <div>Hello</div>;
});

方式二:允许任意属性(快速解决,不推荐用于严格场景)

如果不需要严格的类型检查,可以直接把props声明为any:

const SimpleMemo2 = React.memo((_props: any): JSX.Element => {
    return <div>Hello</div>;
});

方式三:使用泛型指定props类型

先定义props类型,再通过泛型传递给React.memo:

type MyComponentProps = React.HTMLAttributes<HTMLDivElement>;
const SimpleMemo2 = React.memo<MyComponentProps>((_props) => {
    return <div>Hello</div>;
});

这样TypeScript就能正确识别props的合法属性,style等属性就能正常传递了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:55:44