Description
Thank you for your great library.
Started experimenting with it in one of my pet projects and stumbled upon issue with @Injectable
I would love that @Injectable
decorator provides at least some amount of safety, protecting from obvious errors (like not implementing interface that is required by injection token)
Right now, it only works with simple cases when the class is fully the same as the interface
interface Spell {
cast(): void;
}
const Spell = Type<Spell>("Spell");
@Injectable(Spell)
class Fireball {
cast() {}
}
In this case, if you forget to implement interface - there will be a type error.
But as soon as you add more properties/methods to class - typescript starts reporting an error
@Injectable(Spell)
class Fireball {
power = 1;
cast() {}
}
/**
Decorator function return type 'void | Constructor<Spell>' is not assignable to type 'void | typeof Fireball'.
Type 'Constructor<Spell>' is not assignable to type 'void | typeof Fireball'.
Type 'Constructor<Spell>' is not assignable to type 'typeof Fireball'.
Property 'power' is missing in type 'Spell' but required in type 'Fireball'
**/
This error can be kinda silenced
if you use a generic parameter in Injectable
- but in this case, it will stop reporting the issue about not-implemented interface.
// No errors here
@Injectable<Fireball>(Spell)
class Fireball {
foo = 1;
}
There is a similar problem with using multiple tokens - only first token interface is checked and the rest contributes to the error (no checks)
interface Disposable {
dispose(): void;
}
const Disposable = Type<Disposable>("Disposable");
@Injectable(Spell, Disposable)
class Fireball implements Spell, Disposable {
cast() {}
dispose() {}
}
/**
Decorator function return type 'void | Constructor<Spell>' is not assignable to type 'void | typeof Fireball'.
Type 'Constructor<Spell>' is not assignable to type 'void | typeof Fireball'.
Type 'Constructor<Spell>' is not assignable to type 'typeof Fireball'.
Property 'dispose' is missing in type 'Spell' but required in type 'Fireball'.
*/
Looks like it may require a far more complex type definition compared to current one.
I'll experiment with it as well