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

React TypeScript中如何获取ReactNode类型状态的组件名称

问题场景

定义如下React状态:

const [page, setPage] = useState<React.ReactNode>(<UserChats />);

需要获取当前page状态对应的组件名称,尝试通过page.type.name的方式取值时,TypeScript抛出如下类型错误:

Property 'type' does not exist on type 'string | number | boolean | ReactElement<any, string | JSXElementConstructor> | ReactFragment | ReactPortal'.

报错原因是React.ReactNode是覆盖范围极广的联合类型,除React元素外还包含字符串、数字、布尔值、Fragment、Portal等不存在type属性的类型,直接访问type属性不符合类型安全要求。

解决方法
  • 方案1:通过类型守卫收窄类型后取值
    编写工具函数先校验节点类型,确认是合法React元素后再读取组件名,兼容所有React.ReactNode可能的取值场景:
import { ReactElement } from 'react';

const getNodeComponentName = (node: React.ReactNode): string | null => {
  // 过滤非对象、不存在type属性的节点类型(字符串、数字、布尔值、null等)
  if (!node || typeof node !== 'object' || !('type' in node)) {
    return null;
  }
  const element = node as ReactElement;
  // 函数/类组件:type为组件构造函数,直接取name属性
  if (typeof element.type === 'function') {
    return element.type.name;
  }
  // 原生DOM标签:type为标签名字符串
  if (typeof element.type === 'string') {
    return element.type;
  }
  // 特殊节点类型(Fragment、ForwardRef、Suspense等)可按需扩展判断逻辑
  return null;
};

// 调用示例
const currentComponentName = getNodeComponentName(page);
  • 方案2:收窄状态的类型定义
    如果page状态只会存储React组件实例,不会存储字符串、数字、布尔值这类零散内容,无需将状态声明为宽泛的React.ReactNode,直接指定为React.ReactElement即可从根源减少无效联合类型:
import { ReactElement, useState } from 'react';

// 调整状态类型声明
const [page, setPage] = useState<React.ReactElement>(<UserChats />);
// 类型校验后即可安全访问属性
const currentComponentName = typeof page.type === 'function' ? page.type.name : String(page.type);

注意:生产环境代码压缩会混淆函数/类组件的name属性,如果逻辑强依赖组件名判断,建议给组件手动设置displayName静态属性,或者维护组件类型和标识的映射关系,避免压缩后逻辑失效。

内容的提问来源于stack exchange,提问作者José Carlos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:01:08