Skip to content

Generic argument inference no longer working for specific case #39080

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

Closed
MPeloquin opened this issue Jun 15, 2020 · 3 comments
Closed

Generic argument inference no longer working for specific case #39080

MPeloquin opened this issue Jun 15, 2020 · 3 comments
Assignees
Labels
Fix Available A PR has been opened for this issue Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@MPeloquin
Copy link

TypeScript Version: >3.9.2

Search Terms: generic argument inference TS2345

Code

declare namespace React {
    type WeakValidationMap<T> = {
        [K in keyof T]?: null extends T[K] ? string : string
    };

    interface FunctionComponent<P = {}> {
        propTypes?: WeakValidationMap<P>;
    }
}

type A<T1> = <T2>() => React.FunctionComponent<T1 & T2>;

function B<T>(_: A<T>) {}

interface C {
    r: String;
}

function myFunction<T2>(): React.FunctionComponent<C & T2> {
    return {};
}

B(myFunction) // Error
B<C>(myFunction) // No error

Expected behavior: In v3.8.3, the code above did not have any compilation error.

Actual behavior: Compilation error TS2345 when I do not explicitly pass the generic type.

Playground Link: Link

Note: I use React, here I only included the minimal React interfaces to reproduce the issue. The issue is also reproducible with React code directly here

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jun 15, 2020
@RyanCavanaugh RyanCavanaugh added this to the Typescript 4.0.1 milestone Jun 15, 2020
@weswigham
Copy link
Member

Looks to be caused by #37261 - the erased signature seems ok, in theory, but because it erases to any, any & T1 becomes just any, and we lose the ability to infer to T1. If we erase to unknown instead, this should work - unknown will still behave like any in unions still, though (and prevent inference to other union members), which makes me wonder if erasing to a unique anti-any-type-thing might be better - something which evaporates in both unions and intersections, but otherwise behaves anyish.

@davidje13
Copy link

I'm wondering if this is the same issue (also works in 3.8 and fails in 3.9):

interface Input<V> { v: V }
const inner = <V>(fn: <T extends Input<V>>(t: T) => null) => null;
export default () => inner(<T extends Input<string>>(t: T) => null); // <-- error here

Calling inner<string>(...) explicitly works.

This shorter example has the same general structure (an argument which is a function with a complicated parameter), but there's too much going on for me to be sure it's the same bug.

@RyanCavanaugh
Copy link
Member

This behaves as expected now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Available A PR has been opened for this issue Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone
Projects
None yet
6 participants