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

如何组合MotionType与自定义类型传入组件?类型不可分配问题

解决方法

核心问题分析

你的代码出现类型不可分配问题,主要原因有两点:

  • HTMLMotionProps<"div"> 本身已包含 className、onMouseEnter、onMouseLeave 这些属性,手动解构并再次设置时,会和剩余 props 产生属性重复,TypeScript 会检测到类型冲突。
  • 若 MyCustomProps 中存在和 HTMLMotionProps<"div"> 同名的属性,也会导致类型合并时的冲突。

具体修复方案

方案1:排除冲突属性,避免重复传递

通过 Omit 工具类型,从 HTMLMotionProps<"div"> 中排除要手动处理的属性,确保剩余 props 不包含重复项:

import { motion, HTMLMotionProps } from "framer-motion";

// 自定义属性类型示例
type MyCustomProps = {
  myprop: string;
};

// 排除需手动处理的属性,消除类型冲突
type MotionDivProps = Omit<HTMLMotionProps<"div">, "className" | "onMouseEnter" | "onMouseLeave"> & MyCustomProps;

export const MyComponent = ({
  myprop,
  className = "",
  ...props
}: MotionDivProps) => {
  const someFunc = (status: boolean) => {
    // 你的业务逻辑
  };

  return (
    <motion.div
      {...props}
      className={className.trim()}
      onMouseEnter={() => someFunc(true)}
      onMouseLeave={() => someFunc(false)}
    />
  );
};

方案2:兼容外部传入事件

如果需要保留外部传入的 onMouseEnter/onMouseLeave 事件,同时执行内部逻辑,可手动解构外部事件并在内部调用:

import { motion, HTMLMotionProps } from "framer-motion";

type MyCustomProps = {
  myprop: string;
};

type MotionDivProps = HTMLMotionProps<"div"> & MyCustomProps;

export const MyComponent = ({
  myprop,
  className,
  onMouseEnter: externalEnter,
  onMouseLeave: externalLeave,
  ...props
}: MotionDivProps) => {
  const someFunc = (status: boolean) => {
    // 你的业务逻辑
  };

  return (
    <motion.div
      {...props}
      className={className ?? ""}
      onMouseEnter={(e) => {
        externalEnter?.(e);
        someFunc(true);
      }}
      onMouseLeave={(e) => {
        externalLeave?.(e);
        someFunc(false);
      }}
    />
  );
};

方案3:检查自定义属性重名

确认 MyCustomProps 中的属性名没有和 HTMLMotionProps<"div"> 中的属性重复(比如不要定义 className、style 这类已有属性),如果有重名,修改自定义属性名称即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:47:36