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

JSX转TSX时craft.js中Element组件is属性类型不兼容问题

Craft.js Element组件is属性类型错误原因分析

在使用refine.dev和craft.js开发应用、将JSX转为TSX的过程中,在<Element is={Container} />处出现类型错误,以下是相关代码及错误详情:

Builder组件代码

import { Button, Image, Text } from "@shared/components/atoms/components";
import { ColumnRules, Container, FourCol, OneCol, ThreeCol, TwoCol } from "@shared/components/layout/components";

interface BuilderProps {
  onBuilderStatePersist: (value: string) => void;
  initialBuilderState: { buildState: string };
}

export const Builder = ({ onBuilderStatePersist, initialBuilderState }: BuilderProps) => {
  [...]

  return (
    <div style={{ margin: "0 auto", width: "100%", position: "relative" }}>
      <Editor
        resolver={{
          // 自定义组件配置
        }}
      >
          <Grid item xs>
            <Frame data={builderStateRef.current}>
              <Element is={Container} padding={5} background="#eee" canvas />
            </Frame>
          </Grid>
        </Grid>
      </Editor>
    </div>
  );
};

Container组件代码

import { HTMLAttributes, ReactNode } from "react";
import { useNode } from "@craftjs/core";
import { Paper } from "@mui/material";

interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
  id: string;
  background?: string;
  backgroundColor?: string;
  borderRadius?: string;
  padding?: number;
  children?: ReactNode;
}

export const Container = ({ background, padding = 0, children, ...props }: ContainerProps) => {
  const {
    connectors: { connect, drag },
  } = useNode();
  return (
    <Paper
      {...props}
      ref={(ref) => ref && connect(drag(ref!))}
      style={{ margin: "5px 0", background, padding: `${padding}px` }}
    >
      {children}
    </Paper>
  );
};

错误提示

Type '({ background, padding, children, ...props }: ContainerProps) => JSX.Element' is not assignable to type '(({ background, padding, children, ...props }: ContainerProps) => Element) & string'.
Type '({ background, padding, children, ...props }: ContainerProps) => JSX.Element' is not assignable to type 'string'.ts(2322)
Element.d.ts(15, 5): The expected type comes from property 'is' which is declared here on type 'IntrinsicAttributes & { id?: string | undefined; is?: (({ background, padding, children, ...props }: ContainerProps) => Element) | undefined; custom?: Record<string, any> | undefined; children?: ReactNode; canvas?: boolean | undefined; } & ContainerProps'
(property) is?: ((({ background, padding, children, ...props }: ContainerProps) => JSX.Element) & string) | undefined

错误原因

核心问题是类型交叉导致的属性冲突:

  • ContainerProps继承了HTMLAttributes<HTMLDivElement>,而HTML原生的<div>元素有一个is属性(用于自定义内置元素,类型为string)。
  • Craft.js的<Element>组件本身定义了is属性,用于指定要渲染的自定义组件,类型为组件函数。
  • 当<Element>的Props与ContainerProps交叉合并时,is属性的类型变成了组件函数类型 & string——这是一个不可能同时满足的交集类型。你传入的Container是组件函数,无法匹配string类型,因此触发类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 23:30:57