0

Here's my code :

interface IDoc {
  doSomething(): void
}

class IDocFoo implements IDoc {
  doSomething(): void {
    console.log('Do doSomething');
  }
}

class IDocFactory {
  getIDocInstance<T extends IDoc>(): T {
    return new IDocFoo();
  }
}

This code is reduced version of my code, of course.

Typescript shows me an error : Type 'IDocFoo' is not assignable to type 'T' and I don't understand why. Is anybody can explain me why ?

guy777
  • 222
  • 1
  • 14

1 Answers1

1

The full error message is:

Type 'IDocFoo' is not assignable to type 'T'.
  'IDocFoo' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'IDoc'.

The compiler cannot be sure what type you will pass into getIDocInstance(), and it is possible that you could pass in an incompatible type, e.g.:

interface IDoc {
  doSomething(): void
}

class IDocFoo implements IDoc {
  doSomething(): void {
    console.log('Do doSomething');
  }
}

class IDocBar implements IDoc {
  doSomething(): void {
    console.log('Do doSomething');
  }
  doSomethingElse(): void {
    console.log('Do doSomethingElse');
  }
}

class IDocFactory {
  // This will not compile as before, because as the error says, you may pass a
  // different subtype of 'Idoc' to the method; one that IDocFoo is not
  // assignable to.
  static getIDocInstance<T extends IDoc>(): T {
    return new IDocFoo();
  }
}

// Here is an example of how you might pass a different subtype of IDocFoo to
// the factory method.
IDocFactory.getIDocInstance<IDocBar>();

To achieve what you want you'd have to pass the specific class into the factory constructor. See this answer.

Collierre
  • 946
  • 8
  • 16