如何在导出时隐藏泛型组件的注入式Prop?
解决方案
要实现泛型Component对外仅暴露WannaBePropTypes签名,同时由Wrapper自动注入PropThatWillBeInjected属性,可通过类型断言调整组件对外暴露的类型来解决,无需修改组件内部逻辑或添加多余包裹组件。
步骤1:调整Component的导出类型
修改Component.tsx,通过类型断言将组件对外的Props约束改为WannaBePropTypes,保留内部泛型逻辑:
import type { SomeObject, PropTypes, WannaBePropTypes } from './types'; function Component<T extends SomeObject>(props: PropTypes<T>) { const { fn, name } = props; const result = fn(name); return <div>Hello, {result.someKey}</div>; } // 对外暴露的组件类型:仅接受 WannaBePropTypes,同时保留泛型支持 export default Component as <T extends SomeObject>(props: WannaBePropTypes) => ReturnType<typeof Component<T>>;
步骤2:修正Wrapper的子元素类型
调整Wrapper.tsx中的子元素类型,确保类型转换匹配Component的内部实际Props:
import React, { ReactNode, ReactElement, cloneElement } from 'react'; import type { SomeObject, PropTypes, WannaBePropTypes } from './types'; function Wrapper(props: { children: ReactNode }) { const { children } = props; return ( <div id="wrapper"> {React.Children.map( children as ReactElement<WannaBePropTypes>[], (child, index) => cloneElement( // 转换为Component内部实际接受的Props类型 child as ReactElement<PropTypes<SomeObject>>, { ...child.props, fn: (value: string) => ({ someKey: `${value}-${index}`, }), } ) )} </div> ); } export default Wrapper;
效果验证
现在使用组件时,TypeScript将不再要求传入fn属性,仅需提供name:
<Wrapper> <Component name="Alice" /> <Component name="Bob" /> </Wrapper>
此方案的核心是通过类型断言“覆盖”组件对外暴露的签名,同时保证内部逻辑仍能获取到Wrapper注入的fn属性,既满足类型约束需求,又不影响运行时逻辑。
内容的提问来源于stack exchange,提问作者Victor Oliveira
相关产品推荐
相关产品推荐

