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

Function signatures not inferred on JSX prop with complex union #29340

Open
andrewbranch opened this issue Jan 10, 2019 · 0 comments

Comments

@andrewbranch
Copy link
Member

commented Jan 10, 2019

TypeScript Version: 3.3.0-dev.20190109

Search Terms: react function union inference

Code

import * as React from 'react';

interface Props1 {
  onSomething?: (data: number) => any;
}

interface Props2 {
  onSomethingElse?: (data: number) => any;
}

interface PropsA {
  foo: true;
  bar: string;
  fn: (arg: number | undefined) => JSX.Element;
}

interface PropsB {
  foo: false;
  bar: number;
  fn: (arg: number[]) => JSX.Element;
}

type Props = (Props1 | Props2) & (PropsA | PropsB);

declare class Component extends React.Component<Props> {}

<Component
  onSomething={(data) => data}
  foo={false}
  bar={3}
  fn={(arg) => <>{arg.toFixed(3)}</>} // This should be an error, but type argument is `any`
/>

Expected behavior:

  1. (Props1 | Props2) & (PropsA | PropsB) expands to (Props1 & PropsA) | (Props1 & PropsB) | (Props2 & PropsA) | (Props2 & PropsB)
  2. foo={false} narrows that down to intersections that include PropsB
  3. Since PropsA has been eliminated, the only valid signature for the prop fn is (arg: number[]) => JSX.Element
  4. In fn={(arg) => <>{arg.toFixed(3)}</>}, arg should be inferred as number[], which means arg.toFixed(3) should be an error.

Actual behavior:

arg is inferred as any with diagnostic message Parameter 'arg' implicitly has an 'any' type, but a better type may be inferred from usage. [7044], so there's no compilation error for arg.toFixed(3).

Sidenote:
bar={3} shows that this issue is unique to function signatures (I think). It correctly narrows between PropsA and PropsB for bar: string and bar: number, respectively, and enforces that the prop value matches correctly.

Playground Link: anyone have a suggestion for an online playground where I can use JSX and @types/react?

Related Issues: Not sure, didn't find anything that looks similar. Couldn't find any issue mentioning that diagnostic message code.

@weswigham weswigham added the Bug label Jan 10, 2019

@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Mar 14, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.