typescript / expert
Snippet
Typsicheres Dependency-Injection-Registrierungsmuster
Dieses Experten-Muster verwendet opaque Token mit Phantom-Daten-Merkmalen (`_type!: T`), um einen leichtgewichtigen, vollständig typsicheren Dependency-Injection-Container ohne Abhängigkeit von experimentellen Dekoratoren oder Metadaten-Bibliotheken zu bauen.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
abstract class ServiceToken<T> {readonly _type!: T;}function createToken<T>(description: string): ServiceToken<T> {return { description } as unknown as ServiceToken<T>;}class Container {private services = new Map<ServiceToken<any>, any>();register<T>(token: ServiceToken<T>, instance: T): void {this.services.set(token, instance);}resolve<T>(token: ServiceToken<T>): T {const instance = this.services.get(token);if (!instance) throw new Error('Service not registered');return instance as T;}}interface Logger { log(msg: string): void; }const LOGGER_TOKEN = createToken<Logger>('LoggerService');const container = new Container();container.register(LOGGER_TOKEN, { log: console.log });const logger = container.resolve(LOGGER_TOKEN);
Erklärung
1
abstract class ServiceToken<T> { readonly _type!: T; }
Erstellt eine typisierte Token-Markierung mit einem Phantom-Feld für die Kompilierzeit-Typ extraktion.
2
private services = new Map<ServiceToken<any>, any>();
Speichert Dienste intern mit Token als Schlüssel, während die Laufzeit-Nutzlast flexibel bleibt.
3
register<T>(token: ServiceToken<T>, instance: T): void
Stellt sicher, dass die registrierte Dienstinstanz genau dem vom Token vorgegebenen Typ entspricht.
4
resolve<T>(token: ServiceToken<T>): T
Garantiert Kompilierzeit-Rückgabetypsicherheit entsprechend dem übergebenen Token.