Skip to content

Generic checking error #18387

Description

@tinganho

I think #16368 broke this code for me:

class Model {}

class Collection<M extends Model> {
    m: M;
}

class User extends Model {
}

class Users extends Collection<User> {
}

type CollectionClass = typeof Collection;
let a: CollectionClass = Users; // Error 'User' is not assignable to 'M' 

If I provide the --noStrictGenericChecks flag, it compiles without any complaints. Can I correct this without using the flag?

Activity

  1. mhegazy commented on Sep 11, 2017

    @mhegazy
    Contributor

    #16368 is about generic signatures, and i do not see any generic signatures in the code sample in the OP. so please share some context on what is failing, what is the error that is reported, and why do you believe the error is incorrect.

    Before #16368, when generic signatures where compared, all generic parameters were erased to any then the comparison is done. #16368 adds a correct and more strict comparison by instantiating the source in the generic type arguments of the target before doing the check.

  2. tinganho commented on Sep 11, 2017

    @tinganho
    ContributorAuthor

    Sorry forgot to include the errors. I updated the OP.

    User extends Model, and M is constrained to be at least Model. I think it is weird why User is not assignable to M?

    Here is a playground example:
    http://www.typescriptlang.org/play/index.html#src=class%20Model%20%7B%7D%0A%0Aclass%20Collection%3CM%20extends%20Model%3E%20%7B%0A%20%20%20%20m%3A%20M%3B%0A%7D%0A%0Aclass%20User%20extends%20Model%20%7B%0A%7D%0A%0Aclass%20Users%20extends%20Collection%3CUser%3E%20%7B%0A%7D%0A%0Atype%20CollectionClass%20%3D%20typeof%20Collection%3B%0Alet%20a%3A%20CollectionClass%20%3D%20Users%3B

    #16368 introduced the compilation flag --noStrictGenericChecks. So I would assume it introduced the breaking change. Because when I compile with that flag, no errors occurs.

  3. mhegazy commented on Sep 11, 2017

    @mhegazy
    Contributor

    here is a simpler repro:

    //type CollectionClass = typeof Collection;
    type CollectionClass = { new <M extends Model>(): Collection<M> };
    type UserCollectionClass = { new(): Collection<User> };
    
    declare let a: CollectionClass;
    declare let u: UserCollectionClass;
    
    a = u;  // User is not assignable to M

    the check here is telling you that you are replacing a generic function (constructor function for Collection<M>) with one that is more specific one (constructor function for UserCollection ) which is not allowed.

  4. tinganho commented on Sep 11, 2017

    @tinganho
    ContributorAuthor

    OK I see, thanks for the explanation.

  5. locked and limited conversation to collaborators on Jun 14, 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

    Needs More InfoThe issue still hasn't been fully clarified

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions