React组件封装:类型安全地透传组件Props
实现类型安全的通用React封装组件
完全可行,通过TypeScript泛型结合React内置的类型工具,就能实现这个需求。下面是具体的实现方案:
基础实现(无ref支持)
首先定义封装组件的类型和逻辑:
import React from 'react'; // 定义Wrapper的Props类型:泛型C表示被封装的组件类型 type WrapperProps<C extends React.ElementType> = { // 指定要封装的组件 type: C; } // 合并被封装组件的所有Props(排除ref,如需支持ref见下文) & React.ComponentPropsWithoutRef<C>; // 实现Wrapper组件 const Wrapper = <C extends React.ElementType>({ type: Component, ...props }: WrapperProps<C>) => { // 渲染被封装组件并传递所有props return <Component {...props} />; };
使用示例
先定义一个测试用的被封装组件:
// 定义被封装组件的Props类型 type ButtonProps = { foo: string; bar: string; }; // 被封装的按钮组件 const WrappedButton = ({ foo, bar }: ButtonProps) => { return <button>{foo} - {bar}</button>; };
合法调用(类型检查通过)
<Wrapper type={WrappedButton} foo="bar" bar="baz" />
非法调用(类型检查报错)
如果传入被封装组件不存在的Props,TypeScript会直接抛出类型错误:
// 错误:类型“{ type: typeof WrappedButton; foo: string; bar: string; baz: string; }”缺少类型“WrapperProps<typeof WrappedButton>”中的以下属性... <Wrapper type={WrappedButton} foo="bar" bar="baz" baz="invalid" />
支持Ref转发的版本
如果需要让Wrapper支持转发ref到被封装组件,可以用React.forwardRef实现:
const WrapperWithRef = React.forwardRef<React.ElementRef<C>, WrapperProps<C>>( ({ type: Component, ...props }, ref) => { return <Component ref={ref} {...props} />; } );
使用带Ref的Wrapper
const buttonRef = React.useRef<HTMLButtonElement>(null); <WrapperWithRef ref={buttonRef} type={WrappedButton} foo="bar" bar="baz" />
关于你之前遇到的类型错误
你之前用React.ComponentProps时出现晦涩错误,大概率是因为没有正确约束泛型的范围(比如没指定C extends React.ElementType),或者没有正确合并type属性与组件Props的类型。上面的写法通过明确泛型约束、拆分并合并类型,能避免这类模糊的类型报错。
内容的提问来源于stack exchange,提问作者fehrvuerh93
相关产品推荐
相关产品推荐

