Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic React HOCs broken in 3.5.0-rc #31468

Closed
coolkev opened this issue May 19, 2019 · 2 comments
Closed

Generic React HOCs broken in 3.5.0-rc #31468

coolkev opened this issue May 19, 2019 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@coolkev
Copy link

coolkev commented May 19, 2019

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

@OliverJAsh
Copy link
Contributor

if the ComponentClass definition has any other properties this behavior appears

Unfortunately this is working as intended. See #30650 (comment).

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants