Skip to content

Instantly share code, notes, and snippets.

@eser
Created August 28, 2023 22:11
Show Gist options
  • Save eser/40b94fdb9e15c9f8c53fcb057c6ce256 to your computer and use it in GitHub Desktop.
Save eser/40b94fdb9e15c9f8c53fcb057c6ce256 to your computer and use it in GitHub Desktop.
Basic DI with typescript
Symbol.metadata ??= Symbol("metadata");
// base
type ContainerItemKinds = "class" | "value";
type ContainerKey = symbol | string | number;
type ContainerItem = { obj: unknown, kind: ContainerItemKinds };
const container = new Map<ContainerKey, ContainerItem>();
const inject = (key: ContainerKey, value: unknown, kind: ContainerItemKinds = "value") => {
container.set(key, { obj: value, kind: kind });
}
// decorator
function injectable(key?: ContainerKey) {
return (source: any, context: ClassMethodDecoratorContext) => {
if (context.kind === "class") {
const name = key ?? context.name;
inject(name, source, "class");
}
};
}
function di(strings: TemplateStringsArray) {
const name = strings[0];
const item = container.get(name);
if (item === undefined) {
return undefined;
}
if (item.kind === "class") {
const Type = item.obj as { new (): any };
return new Type();
}
return item.obj;
}
@injectable()
class C {
}
@injectable("d")
class D {
}
const c = new C();
console.log(di`C`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment