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 JSX Inference Issue #27411

Closed
quicksnap opened this issue Sep 28, 2018 · 8 comments
Closed

Generic JSX Inference Issue #27411

quicksnap opened this issue Sep 28, 2018 · 8 comments
Labels
Duplicate An existing issue was already created

Comments

@quicksnap
Copy link

quicksnap commented Sep 28, 2018

Tried finding an issue for this, but nothing turned up. I'm getting unexpected behavior with generic JSX:

TypeScript Version: 3.1.1

Search Terms: generic jsx inference

Code

import React, { Component } from 'react';

type Props<T> = {
  generate: (someArg: any) => T;
  consume: (data: T) => React.ReactNode;
};

class Foo<T> extends Component<Props<T>> {}

const fine = (
  <Foo
    generate={() => 123}
    consume={num => num / 2} // Works fine. Inferred type is `number`
  />
);

const error = (
  <Foo
    generate={thisCausesIssues => 123}
    consume={num => num / 2} // Error! Inferred type of `num` is `{}`
  />
);

Expected behavior:

num would infer correctly.

Actual behavior:

num is widened to the {} type. On TS 3.1.1 I get the error above. On ts@next, it seems not to understand my props whatsoever.

Playground Link:

Related Issues:

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Oct 1, 2018
@RyanCavanaugh
Copy link
Member

Same root cause as #25826

@quicksnap
Copy link
Author

Is this to be closed then? Not that I would want that, but that was the fate of the root issue.

@quicksnap
Copy link
Author

quicksnap commented Oct 2, 2018

For this simple type of component, is there a workaround I could do? Not sure where I could annotate to help out TS.

One problem is that this kind of component is used in conjunction with connect() in React/Redux, e.g.

const ConnectedComponent = connect</*inferred generics*/>(/*...*/)(Foo)

And thus the ConnectedComponent loses the ability to pass along Foo's generic parameters.

(Sorry if that use case is confusing--might be especially confusing if you don't use React+Redux)

@mikeb-simspace
Copy link

I seem to have solved the issue by moving the inline function definition into a variable like:

const generate = thisNoLongerCausesIssues => 123
const consume = num => num / 2

const fine = <Foo generate={generate} consume={consume} />

Can anyone confirm that this works for their use case?

@weswigham
Copy link
Member

Those kinds of declarations (ie, lambdas without annotations or context) will issue errors under noImplicitAny. All that will do is swap the inferred {} for an implicit any.

@mikeb-simspace
Copy link

Yes sorry I should have clarified -- take either prop out and annotate and it works fine

@quicksnap
Copy link
Author

@mikeb-simspace Yes--Annotating generate seems to help:

const fine = (
  <Foo
    generate={() => 123}
    consume={num => num / 2} // Works fine. Inferred type is `number`
  />
)

const error = (
  <Foo
    generate={thisCausesIssues => 123}
    consume={num => num / 2} // Error! Inferred type of `num` is `{}`
  />
)

const noError = (
  <Foo
    generate={(noIssues: string) => 123}
    consume={num => num / 2} // Works fine!
  />
)

@typescript-bot
Copy link
Collaborator

This issue has been marked as a duplicate and has seen no activity in the last day. It has been closed for automatic 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

5 participants