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

Generics; ReturnType<Function> not assignable to ReturnType<Function & (conditional type)> #31602

Closed
AnyhowStep opened this issue May 26, 2019 · 4 comments

Comments

@AnyhowStep
Copy link
Contributor

AnyhowStep commented May 26, 2019

TypeScript Version: TS Playground version (3.4.1), 3.5.0-dev.20190523

Search Terms: ReturnType, function, conditional type

Code

declare function doThing<
    F extends () => any
>(
    f: () => ReturnType<F>
): void;

//== This fails ==
type Bar<F extends () => any> = (
    & (() => ReturnType<F>)
    //Should be the same as `unknown`
    & (F extends any ? unknown : unknown)
);

function bar<F extends () => any>(f: F) {
    /*
        Fail
        
        Type 'ReturnType<F>' is not assignable to type
        'ReturnType<(() => ReturnType<F>) & (F extends any ? unknown : unknown)>'
        
        Type '() => any' is not assignable to type
        'F extends any ? unknown : unknown'
    */
    doThing<Bar<F>>(() : ReturnType<F> => {
        return f();
    });

    //Fail
    //Type '() => any' is not assignable to type 'F extends any ? unknown : unknown'
    const t: (
        F extends any ? unknown : unknown
    ) = ((): any => 3);

    //OK!
    const t2: (
        unknown
    ) = ((): any => 3);
}

//== This works ==
type Bar2<F extends () => any> = (
    & (() => ReturnType<F>)
    & unknown
);

function bar2<F extends () => any>(f: F) {
    //OK!
    doThing<Bar2<F>>(() : ReturnType<F> => {
        return f();
    });
}

Expected behavior:

All failures should work.

Actual behavior:

They do not work.

Playground Link: Playground

Related Issues:

@AnyhowStep AnyhowStep changed the title ReturnType<Function> not assignable to ReturnType<Function & (conditional type)> Generics; ReturnType<Function> not assignable to ReturnType<Function & (conditional type)> May 26, 2019
@AnyhowStep
Copy link
Contributor Author

Shorter repro, that shows it also fails for string assignments,

function bar<F>(f: F) {
    //Fail
    //Type '() => any' is not assignable to type 'F extends any ? unknown : unknown'
    const t: (
        F extends any ? unknown : unknown
    ) = ((): any => 3);

    //OK!
    const t2: (
        unknown
    ) = ((): any => 3);

    //Fail
    //Type 'string' is not assignable to type 'F extends any ? string : string'.
    const e: (
        F extends any ? string : string
    ) = ("test" as string);

    //Fail
    //Type 'string' is not assignable to type 'F extends any ? string : string'.
    const e2: (
        Extract<F extends any ? string : string, string>
    ) = ("test" as string);

    //OK!
    const e3: (
        string
    ) = ("test" as string);
}

Playground

@AnyhowStep
Copy link
Contributor Author

For generics, I feel like if the true and false branches of a conditional type both extend some type T, the conditional type itself should also extend T.

I'm unsure how unfeasible it is, though.

@jack-williams
Copy link
Collaborator

For generics, I feel like if the true and false branches of a conditional type both extend some type T, the conditional type itself should also extend T.

See #26933

@AnyhowStep
Copy link
Contributor Author

Ah. I see there's a PR open for it already. I guess I can close this, and wait patiently for #30639 or some successor to get merged.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants