Typescript3.1.3 + Generics, error in type assignment

64 views Asked by At

Consider this situation (dummy example):

class Farmer<A extends Animal<Farmer<A>>>
{
    public animal: A;
    constructor() {
        let a = new Animal(this);
        // ...
    }
}

class Animal<F extends Farmer<Animal<F>>>
{
    public farmer: F;
    constructor(f: F) {
        this.farmer = f;
    }
}

Anyone can explain why in the Farmer constructor (where I pass this argument to new Animal) the above code raises this error?

TS2345: Argument of type 'this' is not assignable to parameter of type 'Farmer<Animal<this>>'.
 Type 'Farmer<A>' is not assignable to type 'Farmer<Animal<this>>'.
  Type 'A' is not assignable to type 'Animal<this>'.
   Type 'Animal<Farmer<A>>' is not assignable to type 'Animal<this>'.
    Type 'Farmer<A>' is not assignable to type 'this'.

The following solve the issue:

class Farmer<A extends Animal<Farmer<A>>>
{
    public animal: A;
    constructor() {
        let a = new Animal(this as Farmer<A>); // works fine
    }
}

Or as alternative:

class Farmer<A extends Animal<Farmer<A>>>
{
    public animal: A;
    constructor() {
        let a = new Animal<Farmer<A>>(this); // works fine
    }
}

The more strange to me is the following:

class Farmer<A extends Animal<Farmer<A>>>
{
    // public animal: A; // removed this line
    constructor() {
        let a = new Animal(this); // now this one works fine too
    }
}

While first two solutions are quite clear, the latter is the one that leaves me more doubtful. Can anyone explain what's happen?

Edit

The following is fine (consider optional the param in Animal constructor):

class Farmer<A extends Animal<Farmer<A>>>
{
    public animal: A;
    constructor() {
        let a = new Animal();
        a.farmer = this; // works fine
    }
}

And here I can't see any difference in types, compared with the first case.

0

There are 0 answers