3

I'm trying to add dependency injection to a plain Typescript project, found an npm package called inversify. So looking at the examples I came across this code:

import { Container, injectable, inject } from "inversify";

@injectable()
class Katana {
    public hit() {
        return "cut!";
    }
}

@injectable()
class Shuriken {
    public throw() {
        return "hit!";
    }
}

@injectable()
class Ninja implements Ninja {

    private _katana: Katana;
    private _shuriken: Shuriken;

    public constructor(katana: Katana, shuriken: Shuriken) {
        this._katana = katana;
        this._shuriken = shuriken;
    }

    public fight() { return this._katana.hit(); };
    public sneak() { return this._shuriken.throw(); };

}

var container = new Container();
container.bind<Ninja>(Ninja).to(Ninja);
container.bind<Katana>(Katana).to(Katana);
container.bind<Shuriken>(Shuriken).to(Shuriken);

What does it mean for class Ninja to implement the class Ninja?

class Ninja implements Ninja {

On the example the container is binding the class to itself, is it related to that?

var container = new Container();
container.bind<Ninja>(Ninja).to(Ninja);
user3531149
  • 1,519
  • 3
  • 30
  • 48

1 Answers1

3

I don't think this has any meaning or adds any type safety. It's just a quirk of how the compiler performs type checking. The implements are checked after the class is already fully typed. So the compiler can check an implements clause that involves the class itself.

In this case it's not particularly useful to use the class in the implements clause (as you are basically saying the class should implement itself which it always does). We can use this feature to do useful things, for example we can ensure the class members are of a specific type

class Test implements Record<keyof Test, () => void> {
  test() { } 
}

class Test2 implements Record<keyof Test2, () => void>{
    test(a: number) { }  // error
}
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
  • Thanks a lot, but why is it that Ninja is the only class that implements itself in the example. – user3531149 Jan 22 '19 at 12:28
  • @user3531149 I would suggest that is just a leftover and a mistake. Could you provide a link to where this example is from ? – Titian Cernicova-Dragomir Jan 22 '19 at 12:31
  • https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md – user3531149 Jan 22 '19 at 12:33
  • 1
    @user3531149 looking at the git history of the page, there was a proposal to remove the `I` from the interfaces. I think someone removed them mechanically without thinking. The code still builds but you are left with the useless implements. – Titian Cernicova-Dragomir Jan 22 '19 at 12:40
  • I had the same question after reading the InversifyJS documentation and wondered why a class would implement itself. Found this and, lo and behold it refers to the exact same line of Ninja code. – strattonn Feb 02 '21 at 23:57