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

React中使用child.type时如何解决TypeScript报错问题

修复React TypeScript组件中child.type的类型错误

问题场景

在以下React TypeScript组件中,TypeScript在child.type处报错:

参数类型'string | JSXElementConstructor'无法赋值给类型'(({ src, alt }: CardImageProps) => Element) | (({ children }: CardBodyProps) => Element)'。类型'string'无法赋值给该联合类型。

原组件代码:

const Card = ({ children }:CardProps) => {

  const allowed = [CardImage, CardBody];

  return (
    <div
      {React.Children.map(children, (child) => {
        if (!allowed.includes(child.type)) return;
        return child;
      })}
    </div>
  );
};

Card.Image = CardImage;
Card.Body = CardBody;

export default Card;

修复方案

1. 明确允许的组件类型

先给allowed数组指定精确的类型,让TypeScript明确数组元素都是自定义组件:

// 定义允许的组件类型
type AllowedCardComponent = typeof CardImage | typeof CardBody;
// 给allowed数组绑定类型
const allowed: AllowedCardComponent[] = [CardImage, CardBody];

2. 过滤原生标签+类型断言

child.type可能是字符串(对应原生HTML标签,比如div),需要先排除这种情况,再用类型断言告诉TypeScript当前child.type属于允许的组件类型:

React.Children.map(children, (child) => {
  // 跳过原生HTML标签
  if (typeof child.type === 'string') return null;
  // 断言类型后检查是否在允许列表中
  if (!allowed.includes(child.type as AllowedCardComponent)) return null;
  return child;
})

3. 完整修复后的代码

import React from 'react';

// 假设基础类型已定义
interface CardProps {
  children: React.ReactNode;
}

interface CardImageProps {
  src: string;
  alt: string;
}

const CardImage = ({ src, alt }: CardImageProps) => <img src={src} alt={alt} />;

interface CardBodyProps {
  children: React.ReactNode;
}

const CardBody = ({ children }: CardBodyProps) => <div>{children}</div>;

const Card = ({ children }: CardProps) => {
  type AllowedCardComponent = typeof CardImage | typeof CardBody;
  const allowed: AllowedCardComponent[] = [CardImage, CardBody];

  return (
    <div>
      {React.Children.map(children, (child) => {
        if (typeof child.type === 'string') return null;
        if (!allowed.includes(child.type as AllowedCardComponent)) return null;
        return child;
      })}
    </div>
  );
};

Card.Image = CardImage;
Card.Body = CardBody;

export default Card;

可选:用类型守卫提升严谨性

如果想要更规范的类型检查,可以自定义类型守卫函数替代类型断言:

function isAllowedCardComponent(
  type: string | JSXElementConstructor<any>
): type is AllowedCardComponent {
  return allowed.includes(type as AllowedCardComponent);
}

之后在map中这样判断:

React.Children.map(children, (child) => {
  if (!isAllowedCardComponent(child.type)) return null;
  return child;
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 02:37:26