简体   繁体   English

使用泛型提取反应组件道具类型

[英]Extract react component prop types with generics

Is there a way to use react's ComponentProps type with generic-typed components?有没有办法将 react 的ComponentProps类型与泛型类型的组件一起使用?

For example:例如:

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>;

I expect MyComponentProps to be something like...我希望MyComponentProps类似于...

type MyComponentPropsExpected<T extends string, N extends number> = {
    text: T;
    number: N;
}

With the generics preserved.保留了泛型。 However, the type just drops the generic and fills all generics with their extends type.但是,该类型只是删除了泛型并用它们的extends类型填充所有泛型。 In this case the actual MyComponentProps type is...在这种情况下,实际的MyComponentProps类型是...

type MyComponentProps = {
    text: string;
    number: number;
}

See demo at https://codesandbox.io/s/react-component-type-generics-6tkr55请参阅https://codesandbox.io/s/react-component-type-generics-6tkr55上的演示

Problem问题

MyComponent has two type parameters T and N with each constrained to string and number respectively: MyComponent有两个类型参数TN ,每个参数分别约束为stringnumber

function MyComponent<T extends string, N extends number>(...) { ... }

However when the MyComponentProps type is created, no types are passed into those parameters:但是,当创建MyComponentProps类型时,不会将任何类型传递给这些参数:

export type MyComponentProps = ComponentProps<typeof MyComponent>;
//                                                   ^^^^^^^^^^^ 
//                                           No type arguments passed in

As a result, the resultant type is the type of the constrained component props.结果,结果类型是受约束的组件道具的类型。

Solution解决方案

TypeScript >=4.7打字稿 >=4.7

You'll need to pass in types to MyComponent :您需要将类型传递给MyComponent

type MyComponentProps = ComponentProps<typeof MyComponent<"text", 2>>;

TypeScript Playground 打字稿游乐场

However, this syntax is only available in TypeScript 4.7+, when instantiation expressions were introduced.但是,当引入实例化表达式时,此语法仅在 TypeScript 4.7+ 中可用。

TypeScript <4.7打字稿 <4.7

Prior to TypeScript 4.7, I would have pulled out the props into its own interface and used that instead of building a type from ComponentProps :在 TypeScript 4.7 之前,我会将 props 提取到它自己的接口中并使用它,而不是从ComponentProps构建类型:

interface MyComponentProps<T extends string, N extends number> {
  text: T;
  number: N;
}

function MyComponent<T extends string, N extends number>({
  text,
  number
}: MyComponentProps<T, N>) {
  ...
}

export const test2: MyComponentProps<"text", 2> = {
  text: "text",
  number: 2
};

TypeScript Playground 打字稿游乐场

Further reading进一步阅读

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM