React TypeScript按钮组件type属性未被识别,泛型用法存疑
问题原因及解决方法
核心问题
你定义的ButtonType泛型参数E完全没用到,始终固定继承HTMLButtonElement的属性,这就导致两个问题:
- 当通过
as切换到非按钮元素(比如div、a)时,type这类按钮专属属性会变成非法Prop - 泛型的动态属性约束完全没生效,没法根据
as的值自动匹配对应元素的合法属性
修复方案
需要把泛型参数E绑定到属性类型上,同时让as的类型和E关联起来,确保属性和元素类型匹配:
import React, { HTMLAttributes, ElementType } from 'react'; import { SemanticElementProps } from "../../utils/SemanticElement"; // 自定义Props,as的类型用ElementType兼容所有HTML元素或自定义组件 export interface ButtonProps<E extends ElementType = 'button'> { as?: E; spin?: boolean; } // 用泛型E动态获取对应元素的属性,自动适配不同元素的合法属性 export type ButtonType<E extends ElementType = 'button'> = React.FC< ButtonProps<E> & React.ComponentPropsWithRef<E> >; // 组件定义时使用泛型,解构属性时处理默认元素 export const Button: ButtonType = ({ as: As = 'button', // 默认渲染button元素 type, className, spin, ...rest }) => { // 用As变量动态渲染指定元素 return <As className={className} type={type} {...rest} />; };
关键改动说明
- 把
ButtonProps的as类型改为ElementType泛型,让它和元素类型E绑定 - 使用
React.ComponentPropsWithRef<E>替代固定的HTMLAttributes<HTMLButtonElement>,自动获取as指定元素的所有合法属性 - 默认值设为
'button',保持组件默认行为和原生按钮一致 - 渲染时用大写开头的
As(符合React组件命名规范)动态渲染元素,确保属性和元素匹配
这样修改后,当你传入as="a"时,TypeScript会自动识别a标签的合法属性,type这类按钮专属属性会被提示为非法;当使用默认的button元素时,type属性会被正常识别。
内容的提问来源于stack exchange,提问作者Nachtfunke
相关产品推荐
相关产品推荐

