如何在泛型组件中使用React的ComponentProps提取属性类型?
问题:React的ComponentProps能否用于泛型组件?
我尝试用ComponentProps提取泛型组件的props类型,但结果丢失了泛型参数,变成了约束的基础类型。示例代码如下:
function MyComponent<T extends string, N extends number>({ text, number }: { text: T; number: N }) { return ( <div> {text} - {number} </div> ); } export type MyComponentProps = ComponentProps<typeof MyComponent>;
我期望得到的MyComponentProps是保留泛型的类型:
type MyComponentPropsExpected<T extends string, N extends number> = { text: T; number: N; }
但实际生成的类型丢失了泛型,直接用约束类型替代:
type MyComponentProps = { text: string; number: number; }
解决方案
ComponentProps的设计逻辑是提取已实例化组件的props类型,当传入泛型组件的typeof类型时,TypeScript会自动将泛型参数替换为它们的约束类型(也就是示例中的string和number),所以无法直接保留泛型。
要保留泛型的props类型,有两种更可靠的方式:
1. 提前手动定义泛型Props类型
最直接的方式是先定义带泛型的Props类型,再让组件使用它:
type MyComponentProps<T extends string, N extends number> = { text: T; number: N; }; function MyComponent<T extends string, N extends number>(props: MyComponentProps<T, N>) { return ( <div> {props.text} - {props.number} </div> ); } // 直接复用提前定义好的泛型Props类型 export type ReusedMyComponentProps<T extends string, N extends number> = MyComponentProps<T, N>;
2. 自定义泛型工具类型
如果不想提前定义Props类型,可以写一个自定义工具类型来提取泛型组件的原始props泛型:
import type { ComponentType } from 'react'; type GenericComponentProps<C extends ComponentType<any>> = C extends ComponentType<infer P> ? P : never; // 使用自定义工具类型提取泛型Props export type MyComponentProps<T extends string, N extends number> = GenericComponentProps<typeof MyComponent<T, N>>;
这种方式通过infer保留了组件的泛型参数,能准确提取带泛型的props类型。
内容的提问来源于stack exchange,提问作者Nickofthyme
相关产品推荐
相关产品推荐

