Modern Full-Stack – Typescript Class Decorators & Dependency Injections

Serverless eröffnet riesige Potenziale für die Frontend-Entwicklung. Als Fullstack-Entwickler berichtet unser Autor Jannik an dieser Stelle regelmäßig von seinen Erfahrungen aus dem Projektalltag, spricht über aktuelle Trends und gibt hilfreiche Tipps rund um AWS, Tailwind und Co.

In der heutigen Folge lernt ihr, wie TypeScript Class Decorators in Frameworks für die Dependency Injection genutzt werden können.

Inhalt:

  1. Class Decorater mit generischer Beschränkung
  2. Welche Einschränkungen liegen vor?
  3. Beispiele
    3.1. Eigenschaften hinzufügen
    3.2. Modifizierung einer Class verhindern
    3.3 Dependency Injection
  4. Zusammenfassung

Mithilfe von Class Decorators haben wir Zugang zu dem Konstruktor sowie dessen Prototyp. Eine Erklärung von Konstruktoren und Prototypen findet Ihr in dieser MDN Erklärung von Inheritance.

Damit können wir die gesamte Class modifizieren. Mithilfe des Prototypen können wir Methoden hinzufügen, Standardwerte für an den Konstruktor übergebene Parameter festlegen, Attribute hinzufügen, entfernen oder verpacken.

 

1. Class Decorator mit generischer Beschränkung

In TypeScript decorators basic post habe ich bereits die Signatur der verschiedenen Typen von Decorators beschrieben, inklusive dem Class Decorator.

Wir können das TypeScripts Keyword `extends` benutzen, um sicherzustellen, dass das Target ein Konstruktor ist. Das erlaubt es uns, das `target` als Konstruktor zu behandeln (daher habe ich es im folgenden Beispiel in `constructor` umbenannt) und Features wie die Erweiterung von `constructor` zu nutzen.

Ein weiteres Beispiel findest du im Playground.

 

 

2. Welche Einschränkungen liegen vor?

Bei der Nutzung eines Class Decorators gibt es eine Einschränkung bei der Modifizierung der Class, die Ihr kennen solltet:

“TypeScript unterstützt die Laufzeit Symantik des Decorator Vorschlags, aber es zeigt aktuell nicht die Änderungen gegenüber der Form des Targets. Das Hinzufügen oder Entfernen von Methoden und Eigenschaften wird beispielsweise nicht vom Type System erfasst.”

Ihr könnt die Class modifizieren, aber ihr Typ wird nicht geändert. Öffnet das Beispiel im nächsten Abschnitt von Playground, um eine Vorstellung davon zu bekommen, was das bedeutet.

Es gibt seit 2015 ein offenes Problem in der TypeScript Repo, das diese Beschränkung verdeutlicht.

Außerdem gibt es einen Workaround, bei dem Schnittstellen zusammengeführt werden, aber diese Methode verfehlt irgendwie den Sinn, den Decorator überhaupt zu verwenden.

Auch hierzu findest du in Playground ein offenes Beispiel. 

 

 

3. Einige Beispiele

Zum Schluss noch ein paar Beispiele, um Euch eine Vorstellung davon zu geben, was Ihr tun könnt. Es gib nur sehr wenige Einschränkungen in dem, was man tun kann, da man ja im Grunde die gesamte Class ersetzen kann.

 

3.1 Eigenschaften hinzufügen

Das folgende Beispiel zeigt, wie man zusätzliche Attribute zu der Class hinzufügen oder diese modifizieren kann, indem man eine Funktion an die Decorator Factory weitergibt. Schau dir hierzu TypeScript decorators basics post für weitere Details zum Konzept der Decorator Factories an.

Auch hierzu gibt es ein offenes Beispiel in Playground.

Das kann sehr nützlich sein für Entities, die man irgendwo speichern möchte. Man kann die Methode weitergeben, um die `id` von Entities zu generieren. Der Timestamp, der so erzeugt wird, wird dann automatisch eingestellt. Man könnte diese Beispiele auch erweitern, indem man z.B. eine Funktion erstellt, die den Timestamp formatiert.

 

3.2 Modifizierung einer Class verhindern

In diesem Beispiel nutzen wir `Object.seal()` am Konstruktor selbst und seinem Prototyp, um zu verhindern, dass Eigenschaften hinzugefügt oder entfernt werden und um existierende Eigenschaften unkonfigurierbar zu machen. Das könnte nützlich sein für (Teile von) Libraries, die modifiziert werden müssen.

Schau dir dazu ein Beispiel in Playground an.



3.3 Dependency Injection

Eine fortgeschrittene Nutzung von Class Decorators (in Synergie mit Parameter Decorators) wäre die Dependency Injection (DI). Dieses Konzept wird stark genutzt von Frameworks wie Angular und NestJS .

Ich gebe Euch ein einfaches Arbeitsbeispiel. Hoffentlich hilft Euch das dabei, eine Vorstellung vom Gesamtkonzept zu bekommen.

DI kann man in drei Schritten erreichen:

  1. Registrierung einer Class, die auch in andere Classes injizierbar sein soll, in einem `Container` (auch genannt `Registry`).
  2. Nutzung eines Parameter Decorators, um die Classes, die injiziert werden sollen, zu kennzeichnen (hier: `@inject()`; meistens verwendet im Konstruktor dieser Class, genannt constructor based injection).
  3. Nutzung eines Class Decorators (hier: @injectionTarget) für eine Class, die das Target der Injection sein soll.

Das folgende Beispiel zeigt wie die `UserRepository` in den `UserService` injiziert wird. Der so erzeugte Fall des `UserService` hat Zugriff zu einem Fall des `UserRepository`, ohne dass er einen Repository an seinen Konstruktor weitergegeben hat (er wurde injiziert). Ihr könnt die Erklärung hierzu in Form von Kommentaren im Code finden.

Das gesamte Beispiel findet ihr in Playground.

Das ist natürlich nur ein einfaches Beispiel, in dem viele Features fehlen. Aber es zeigt gut das Potential der Class Decorators sowie des Konzepts von DI.

Es gibt ein paar Libraries, die DI implementieren:

 

 

4. Zusammenfassung

 

Class Decorators haben ein enormes Potential, da Ihr damit die gesamte Class ändern könnt, die diese dekorieren. Es gibt aber eine Einschränkung, da der Typ der Class, die durch den Decorator geändert wird, nicht in dieser Änderung aufgezeigt wird.

Habt Ihr schonmal Eure eigenen Class Decorators geschrieben? Welche Class Decorators habt Ihr genutzt?

 

jannik-wempe_foto

Jannik Wempe - war Software Engineer bei iteratec. Als Full-Stack Entwickler programmierte er individuelle Lösungen für den Kunden, egal ob im Front- oder Backend. Wir schätzen seinen Beitrag und informieren, dass er nicht mehr bei iteratec tätig ist.

 

Dieser Blogbeitrag wurde aus dem Englischen übersetzt und erschien ursprünglich auf: https://blog.jannikwempe.com/typescript-class-decorators-incl-dependency-injection-example

Mehr Infos und weitere interessante Beiträge unter: https://blog.jannikwempe.com/

Tags: Individualsoftwareentwicklung

Verwandte Artikel

70% aller IT-Modernisierungsprojekte scheitern! Mit generativer künstlicher Intelligenz (Gen AI) kann das Risiko bereits...

Mehr erfahren

Topics: Individualsoftwareentwicklung

Die richtige Microfrontend-Architektur kann Teams dabei helfen, effizient an komplexen Webanwendungen zu arbeiten und flexibel...

Mehr erfahren

Topics: Individualsoftwareentwicklung

Many leaders have high expectations when starting an agile transformation. Just imitating what, e.g. the Scrum Guide describes,...

Mehr erfahren

Topics: Individualsoftwareentwicklung