Skip to content

Generic type parameter is lost after generic member call #11584

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
alexfoxgill opened this issue Oct 13, 2016 · 3 comments · Fixed by #55514
Closed

Generic type parameter is lost after generic member call #11584

alexfoxgill opened this issue Oct 13, 2016 · 3 comments · Fixed by #55514
Labels
Bug A bug in TypeScript
Milestone

Comments

@alexfoxgill
Copy link

alexfoxgill commented Oct 13, 2016

This is the simplest version of this bug I could find:

function example<T1>() {
    let x = {
        foo: <T2>(t2: T2) => x,
        bar: (t1: T1) => x
    }
    return x;
}

example<number>()
    .foo("hello")
    .bar(1) // Argument of type 'number' is not assignable to parameter of type 'T1'

The call to bar fails to compile. The type is example<number>, so it should compile.

If I try to add type information to x, another compilation error occurs:

type Example<T1> = {
    foo: <T2>(t2: T2) => Example<T1>,
    bar: (t1: T1) => Example<T1>
}
function example<T1>() {
    let x: Example<T1> = {
        foo: <T2>(t2: T2): Example<T1> => x,
        bar: (t1: T1): Example<T1> => x
    }
    return x;
}

example<number>()
    .foo("hello")
    .bar(1)

Type '{ foo: (t2: T2) => Example; bar: (t1: T1) => Example; }' is not assignable to type 'Example'.
Types of property 'foo' are incompatible.
Type '(t2: T2) => Example' is not assignable to type '(t2: T2) => Example'.
Type 'Example' is not assignable to type 'Example'.
Types of property 'bar' are incompatible.
Type '(t1: T1) => Example' is not assignable to type '(t1: T1) => Example'.
Types of parameters 't1' and 't1' are incompatible.
Type 'T1' is not assignable to type 'T1'.
let x: Example

Interestingly, removing either the foo or bar methods will allow the code to successfully compile:

type Example<T1> = {
    foo: <T2>(t2: T2) => Example<T1>,
    //bar: (t1: T1) => Example<T1>
}
function example<T1>() {
    let x: Example<T1> = {
        foo: <T2>(t2: T2): Example<T1> => x,
        //bar: (t1: T1): Example<T1> => x
    }
    return x;
}
type Example<T1> = {
    //foo: <T2>(t2: T2) => Example<T1>,
    bar: (t1: T1) => Example<T1>
}
function example<T1>() {
    let x: Example<T1> = {
        //foo: <T2>(t2: T2): Example<T1> => x,
        bar: (t1: T1): Example<T1> => x
    }
    return x;
}
@alexfoxgill
Copy link
Author

Classes do not have this issue:

class Example<TFoo> {
    constructor(foo: TFoo) {
    }

    foo(f: TFoo) {
        return this;
    }

    bar<TBar>(b: TBar) {
        return this;
    }
}

new Example(0)
    .bar("hello")
    .foo(1)

@mhegazy mhegazy added the Bug A bug in TypeScript label Oct 17, 2016
@mhegazy mhegazy added this to the Future milestone Oct 17, 2016
@sandersn sandersn removed their assignment Jan 7, 2020
@Andarist
Copy link
Contributor

This has already been fixed: TS playground, cc @jakebailey

@jakebailey
Copy link
Member

The error changed in #10676 for 2.0 to instead mention 1, then fully fixed in #13356 for 2.1. Though, I'm not totally sure we have a test for this, given what changed in the latter PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants