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

React+NextJS中如何正确为svg标签内的SVG标记设置TS类型

SvgIcon类型约束实现方案

修正类型定义解决报错

你之前遇到类型报错的核心原因是使用了不存在的ReactSVG类型,React类型包中内置的SVG元素实例类型为ReactSVGElement,直接替换即可实现基础类型约束:

import type { ReactSVGElement, ReactNode } from 'react';

interface SvgIconProps {
  children: ReactSVGElement | ReactSVGElement[];
  strokeWidth?: number;
  width?: number;
  height?: number;
  className?: string;
}

export const SvgIcon = ({
  children,
  strokeWidth = 1,
  width = 24,
  height = 24,
  className,
}: SvgIconProps) => {
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      className={className}
      fill="none"
      viewBox={`0 0 ${width} ${height}`}
      stroke="currentColor"
      strokeWidth={strokeWidth}
      width={width}
      height={height}
    >
      {children}
    </svg>
  );
};

修改后如果传入<div />、普通文本这类非SVG子元素,TypeScript会直接抛出类型错误,符合约束需求。

同步调整ButtonWithIcon类型

将组件中svgMarkup的类型和SvgIcon的children类型保持一致,普通按钮内容继续保留ReactNode类型即可,实现两类子元素的类型区分:

import type { ReactSVGElement, ReactNode } from 'react';
import { SvgIcon } from "../SvgIcon";

interface ButtonWithIconProps {
  children: ReactNode;
  onClick: (...args: any[]) => void;
  side: "left" | "right";
  svgMarkup: ReactSVGElement | ReactSVGElement[];
}

export const ButtonWithIcon = ({
  children,
  onClick,
  side,
  svgMarkup,
}: ButtonWithIconProps) => {
  return (
    <button onClick={onClick} className="">
      {side === "left" && <SvgIcon>{svgMarkup}</SvgIcon>}
      {children}
      {side === "right" && <SvgIcon>{svgMarkup}</SvgIcon>}
    </button>
  );
};

注意:如果你需要传入封装好的自定义图标组件(比如<HomeIcon />),需要给自定义图标组件标注返回值类型为ReactSVGElement,否则类型校验会不通过。如果项目中自定义图标组件较多,可以将类型调整为ReactSVGElement | ReactSVGElement[] | (() => ReactSVGElement)兼容组件传参。


内联SVG vs img元素选型建议

你倾向于用内联SVG的写法完全合理,两种方案的适用场景如下:

  • 选择内联SVG:如果图标需要动态修改颜色(比如继承currentColor随按钮文字变色)、调整描边粗细、响应交互状态样式,内联SVG是最优方案,不需要把SVG文件存放到public目录,直接作为JSX编写即可,打包时也会自动被构建工具处理。
  • 选择img元素:仅适合不需要修改内部样式、纯静态展示的装饰类图标,这种场景下img加载的SVG无法通过CSS修改内部的fill、stroke属性,灵活度远低于内联SVG,不适合通用图标组件场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:15:39