У меня такой подход получился в TypeScript сам по себе из-за технических ограничений, но вот щас кажется, что это и логически вполне разумно.
Там интерфейсы - это чисто compile-time штука для проверки типов, со своим пространством имен, которое не эмитит js-кода, так что в DI их использовать напрямую не получится. А вот абстрактный класс компилируется, так что пожалуйста.
Потому всякие Logger-ы (то, что нужно инжектить) - это у меня pure abstract-классы, а всякие Fooable - интерфейсы (мне в рантайме о них знать и не надо).
Правда, TS позволяет указывать в implements классы (это означает - использовать фактический интерфейс класса в качестве, собственно, интерфейса). Я так и пишу, pure abstract classes это как бы просто такой workaround, чтобы не связываться с дублированием интерфейсов символами (или чем-то еще, что емитит JS) только ради DI. Теперь задумался, может, лучше и в extends