8000 Type definition for Injectable decorator is not fully type safe · Issue #21 · exuanbo/di-wise · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Type definition for Injectable decorator is not fully type safe #21
Open
@srg-kostyrko

Description

@srg-kostyrko

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0