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

React+TypeScript中泛型extends未强制校验组件属性问题

问题原因

问题1:传入不满足props要求的Component不报错

你当前的泛型写法下,TypeScript 会优先从传入的component参数反向推断泛型ComponentProps的实际类型,再校验是否符合约束。而 React 组件类型ComponentType<P>的参数P处于逆变位置:只要传入的组件接收的属性是ComponentProps的子集,TypeScript 就会认为类型兼容(组件忽略额外传入的onBlur属性不属于类型错误),所以即使传入的组件没有定义onBlur属性,也不会触发约束校验。

问题2:内部渲染Component时报错

这是 TypeScript 4.4 版本的泛型推断限制:你手动拼接的rest+onChange+onBlur属性,TypeScript 无法自动识别为完整的ComponentProps类型,会误判属性不完整。


解决方案

调整泛型的定义顺序,先从传入的component提取属性类型P,再直接约束P必须包含onChange和onBlur,解决逆变导致的校验失效问题;内部渲染时对拼接后的属性做一次类型断言,解决泛型推断限制导致的误报。


修复后完整代码

import React from 'react';

function Component({
  onChange,
}: {
  onChange: (event: React.ChangeEvent) => void;
}) {
  return <input onChange={onChange} />;
}

// 调整泛型顺序:先获取组件Props类型P,再约束P必须包含onChange和onBlur
function Field<
  P extends {
    onChange: (event: React.ChangeEvent) => void;
    onBlur: (event: React.FocusEvent) => void;
  }
>({
  component: Component,
  ...rest
}: {
  component: React.ComponentType<P>;
} & Omit<P, "onChange" | "onBlur">) {
  // 拼接属性后断言为P类型,解决TS泛型推断误报
  const componentProps = {
    ...rest,
    onChange: (event: React.ChangeEvent) => {/* 业务逻辑 */},
    onBlur: (event: React.FocusEvent) => {/* 业务逻辑 */},
  } as P;

  return <Component {...componentProps} />;
}

export function App() {
  // 现在这里会正确报错:Component的props缺少必选属性onBlur
  return <Field component={Component} />;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:54:07