Skip to content

Type inference not working for this particular use of Generics? #8952

Description

@coreh

Hey there. I was experimenting with generics, and noticed that type inference didn't work as I expected for this particular case. I'm not entirely sure if this is an actual blind spot of the type inference mechanism, or if my declaration doesn't mean what I think it means. it's a bit similar to the “Curiously recurring template pattern” described on #5949, but isn't actually the CRTP, since there's no actual recursion involved. Thanks in advance for looking into this issue.

TypeScript Version:

1.8.10

Code

interface IFoo {
    foo: 'foo'; // Could be anything
}

interface IWrapped<I> {
    getObject(): I;
}

function unwrap<I, T extends IWrapped<I>>(x: T): I {
    return x.getObject();
}

let x: IWrapped<IFoo>/* = ... */;
let y = unwrap<IFoo, IWrapped<IFoo>>(x); // Type is IFoo (correct)
let z = unwrap(x); // Type is {} (incorrect?)

Expected behavior:

I expected the compiler to infer the type of z as being IFoo, like when using explicit generic parameters on y.

Actual behavior:

The compiler inferred the type of z as being {}.

Activity

  1. Arnavion commented on Jun 3, 2016

    @Arnavion
    Contributor

    Note that in this particular case you can write it with just one generic parameter and not hit the issue:

    function unwrap<I>(x: IWrapped<I>): I {

    but yes, it does look like a bug.

  2. DanielRosenwasser commented on Jun 3, 2016

    @DanielRosenwasser
    Member

    I think this is a symptom of the issue Vincent Siao (@vsiao) pointed out in #7234.

  3. ahejlsberg commented on Jun 3, 2016

    @ahejlsberg
    Member

    This is by design. Inference only infers from the arguments passed to the function to the declared parameters, it does not factor in constraints. Constrains are simply checks that are performed after inference completes. In your example there's really no reason to have two type parameters (and you should never have type parameters you don't need), but there are indeed situations where you want to infer multiple type parameters from a single argument. #7234 is about those scenarios.

  4. coreh commented on Jun 3, 2016

    @coreh
    Author

    Hey there, thanks for looking into this!

    In hindsight I have no idea why I didn't think of

    function unwrap<I>(x: IWrapped<I>): I {

    and instead went with the way more complicated construct.

    Really excited about how powerful the type system is becoming. The & trick to infer multiple types on #7234 is also really cool.

  5. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    By DesignDeprecated - use "Working as Intended" or "Design Limitation" instead

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions