我该如何编写一个接受组件并将其prop类型用作第二个参数类型的泛型
可以说我传入的类型为/var/lib/docker/containers/<containerid>/<path>
我如何提取React.FunctionComponent<IMovieShowcase>
的类型
IMovieShowcase
答案 0 :(得分:1)
我们可以使用TypeScript的type inference in conditional types。
此InferProps
接受名为Component
的通用名称。因此它可以用作InferProps<YourComponent>
来返回道具的类型。据我所知,有ComponentClass
和FunctionComponent
类型是有效的React组件。由于必须同时处理这两种情况,因此我们可以使用嵌套条件(因此使用双?
)。
第一个条件语句Component extends React.ComponentClass<infer Props>
表示如果我们的Component
扩展了React.ComponentClass
,则infer
扩展了Props
并返回了该类型。如果不是,请检查Component extends React.FunctionComponent<infer Props>
。如果Component
扩展了React.FunctionComponent
,则infer
Props
并返回该类型。否则,请返回never
,因为我们不确定如何处理或处理什么,所以我们无法推断道具。
type InferProps<
Component extends ComponentTypes
> = Component extends React.ComponentClass<infer Props>
? Props
: Component extends React.FunctionComponent<infer Props>
? Props
: never;
在简化示例中与您提供的代码一起使用:
import * as React from "react";
type ComponentTypes = React.ComponentClass<any> | React.FunctionComponent<any>;
type InferProps<
Component extends ComponentTypes
> = Component extends React.ComponentClass<infer Props>
? Props
: Component extends React.FunctionComponent<infer Props>
? Props
: never;
function renderWithProviders<T extends ComponentTypes>(
Component: T,
props: InferProps<T>
) {
return <Component {...props} />;
}
class Test extends React.Component<{ foo: string }> {
render() {
return null;
}
}
const Another = (props: { baz: number }) => null;
// Valid:
renderWithProviders(Test, { foo: "bar" });
// Valid:
renderWithProviders(Another, { baz: 1 });
// Invalid:
// Object literal may only specify known properties,
// and 'baz' does not exist in type '{ foo: string; }'
renderWithProviders(Test, { foo: "bar", baz: "foo" });
// Invalid:
// The expected type comes from property 'baz' which is
// declared here on type '{ baz: number; }'
renderWithProviders(Another, { baz: "nope" });