Closed
Description
TypeScript Version: typescript@3.5.0-dev.20190518
Search Terms:
hoc, Higher order type inference
Code
Here is the code from the example: https://devblogs.microsoft.com/typescript/announcing-typescript-3-5-rc/#higher-order-type-inference-from-generic-constructors
type ComponentClass<P> = new (props: P) => Component<P>;
declare class Component<P> {
props: P;
constructor(props: P);
}
declare function myHoc<P>(C: ComponentClass<P>): ComponentClass<P>;
type NestedProps<T> = { foo: number, stuff: T };
declare class GenericComponent<T> extends Component<NestedProps<T>> {
}
// type is 'new <T>(props: NestedProps<T>) => Component<NestedProps<T>>'
const GenericComponent2 = myHoc(GenericComponent);
Expected behavior:
Should work the same when using "React.Component/Class" instead of inline definitions.
declare function myHoc<P>(C: React.ComponentClass<P>): React.ComponentClass<P>;
type NestedProps<T> = { foo: number, stuff: T };
declare class GenericComponent<T> extends React.Component<NestedProps<T>> {
}
// type should be 'new <T>(props: NestedProps<T>) => React.Component<NestedProps<T>>'
// actual type is 'React.ComponentClass<NestedProps<unknown>, any>'
const GenericComponent2 = myHoc(GenericComponent);
Actual behavior:
The component returned from the HOC loses it's generic type parameter and instead uses unknown.
React.ComponentClass<NestedProps<unknown>, any>
I was able to narrow down the issue to the ComponentClass definition. Using the example type works, or using an simple interface works. But if the ComponentClass definition has any other properties this behavior appears.
// works
type ComponentClass<P> = new (props: P) => Component<P>;
// works
interface ComponentClass<P = {}> {
new (props: P, context?: any): Component<P>;
}
// does not work
interface ComponentClass<P = {}> {
new (props: P, context?: any): Component<P>;
displayName?: string;
}
Playground Link:
Related Issues:
#30650