React泛型Slides组件类型不兼容错误解决方案求助
解决React泛型Slides组件类型不兼容问题
我尝试实现一个通用的Slides组件,通过泛型数据数组映射生成不同类型的幻灯片组件,代码如下:
export interface BaseSlideProps { id: string } interface Props<T = BaseSlideProps> { data: T[] Component?: React.FC<T> } export const Slides = <T extends BaseSlideProps>({ data, Component = Slide }: Props<T>) => { return ( <div> <div> {data.map((slide) => ( <Component key={slide.id} {...slide} /> ))} </div> </div> ) } export interface SlideProps extends BaseSlideProps{ id: string } export const Slide: React.FC<SlideProps> = ({ }) => { return ( <div> </div> ) }
运行后出现类型错误:
Type 'FC<SlideProps>' is not assignable to type 'FC<T & BaseSlideProps>'. Types of property 'propTypes' are incompatible. Type 'WeakValidationMap<SlideProps> | undefined' is not assignable to type 'WeakValidationMap<T & BaseSlideProps> | undefined'. Type 'WeakValidationMap<SlideProps>' is not assignable to type 'WeakValidationMap<T & BaseSlideProps>'.ts(2322)
问题原因
TypeScript 认为默认的Slide组件(接收SlideProps)无法适配泛型T(T extends BaseSlideProps),因为T可能包含比SlideProps更多的属性,导致函数组件类型不兼容。
修复方案
方案一:统一默认组件的类型约束
由于SlideProps和BaseSlideProps的内容完全一致,直接让Slide组件接收BaseSlideProps类型,这样它能兼容所有T extends BaseSlideProps的泛型类型:
export interface BaseSlideProps { id: string } interface Props<T = BaseSlideProps> { data: T[] Component?: React.FC<T> } // 直接使用BaseSlideProps作为Slide组件的props类型 export const Slide: React.FC<BaseSlideProps> = ({ }) => { return ( <div></div> ) } export const Slides = <T extends BaseSlideProps>({ data, Component = Slide }: Props<T>) => { return ( <div> <div> {data.map((slide) => ( <Component key={slide.id} {...slide} /> ))} </div> </div> ) }
方案二:添加类型断言
如果需要保留SlideProps的定义,可以在赋值默认组件时用类型断言告诉TypeScript该兼容是安全的:
export interface BaseSlideProps { id: string } interface Props<T = BaseSlideProps> { data: T[] Component?: React.FC<T> } export interface SlideProps extends BaseSlideProps{ id: string } export const Slide: React.FC<SlideProps> = ({ }) => { return ( <div></div> ) } export const Slides = <T extends BaseSlideProps>({ data, Component = Slide as React.FC<T> }: Props<T>) => { return ( <div> <div> {data.map((slide) => ( <Component key={slide.id} {...slide} /> ))} </div> </div> ) }
额外提示
如果后续SlideProps会扩展更多属性,建议优先使用方案二,或者确保默认组件能接收所有可能的T类型属性(比如使用Partial<T>或让SlideProps继承T的属性)。
内容的提问来源于stack exchange,提问作者Marc Frame
相关产品推荐
相关产品推荐

