@travetto/di 7.0.0-rc.1 → 7.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -135,7 +135,7 @@ The [@Inject](https://github.com/travetto/travetto/tree/main/module/di/src/decor
135
135
  **Code: Example Injectable with dependencies as Inject fields**
136
136
  ```typescript
137
137
  import { Injectable, Inject } from '@travetto/di';
138
- import { DependentService } from './dep.ts';
138
+ import { DependentService } from './dependency.ts';
139
139
 
140
140
  @Injectable()
141
141
  class CustomService {
@@ -153,15 +153,15 @@ The [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/d
153
153
  **Code: Example Injectable with dependencies in constructor**
154
154
  ```typescript
155
155
  import { Injectable } from '@travetto/di';
156
- import { DependentService } from './dep.ts';
156
+ import { DependentService } from './dependency.ts';
157
157
 
158
158
  @Injectable()
159
159
  class CustomService {
160
160
 
161
161
  dependentService: DependentService;
162
162
 
163
- constructor(svc: DependentService) {
164
- this.dependentService = svc;
163
+ constructor(service: DependentService) {
164
+ this.dependentService = service;
165
165
  }
166
166
 
167
167
  async coolOperation() {
@@ -176,7 +176,7 @@ Via [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/d
176
176
  ```typescript
177
177
  import { InjectableFactory } from '@travetto/di';
178
178
 
179
- import { DependentService, CustomService } from './dep.ts';
179
+ import { DependentService, CustomService } from './dependency.ts';
180
180
 
181
181
  class Config {
182
182
  @InjectableFactory()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/di",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.3",
4
4
  "description": "Dependency registration/management and injection support.",
5
5
  "keywords": [
6
6
  "ast-transformations",
@@ -27,10 +27,10 @@
27
27
  "directory": "module/di"
28
28
  },
29
29
  "dependencies": {
30
- "@travetto/registry": "^7.0.0-rc.1"
30
+ "@travetto/registry": "^7.0.0-rc.3"
31
31
  },
32
32
  "peerDependencies": {
33
- "@travetto/transformer": "^7.0.0-rc.1"
33
+ "@travetto/transformer": "^7.0.0-rc.3"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
36
  "@travetto/transformer": {
package/src/decorator.ts CHANGED
@@ -4,17 +4,17 @@ import { CONSTRUCTOR_PROPERTY } from '@travetto/schema';
4
4
  import { InjectableCandidate, ResolutionType } from './types.ts';
5
5
  import { DependencyRegistryIndex } from './registry/registry-index.ts';
6
6
 
7
- const fromArg = <T extends { qualifier?: symbol }>(arg?: T | symbol): T =>
8
- typeof arg === 'symbol' ? castTo({ qualifier: arg }) : (arg ?? castTo<T>({}));
7
+ const fromInput = <T extends { qualifier?: symbol }>(input?: T | symbol): T =>
8
+ typeof input === 'symbol' ? castTo({ qualifier: input }) : (input ?? castTo<T>({}));
9
9
 
10
10
  /**
11
11
  * Indicate that a class is able to be injected
12
12
  * @augments `@travetto/schema:Schema`
13
13
  * @kind decorator
14
14
  */
15
- export function Injectable(config?: Partial<InjectableCandidate> | symbol) {
15
+ export function Injectable(input?: Partial<InjectableCandidate> | symbol) {
16
16
  return <T extends Class>(cls: T): void => {
17
- DependencyRegistryIndex.getForRegister(cls).registerClass(fromArg(config));
17
+ DependencyRegistryIndex.getForRegister(cls).registerClass(fromInput(input));
18
18
  };
19
19
  }
20
20
 
@@ -26,15 +26,15 @@ export type InjectConfig = { qualifier?: symbol, resolution?: ResolutionType };
26
26
  * @augments `@travetto/schema:Input`
27
27
  * @kind decorator
28
28
  */
29
- export function Inject(config?: InjectConfig | symbol) {
30
- return (instanceOrCls: Class | ClassInstance, property?: string | symbol, idx?: number | PropertyDescriptor): void => {
31
- const cfg = fromArg(config);
29
+ export function Inject(input?: InjectConfig | symbol) {
30
+ return (instanceOrCls: Class | ClassInstance, property?: string, idx?: number | PropertyDescriptor): void => {
31
+ const config = fromInput(input);
32
32
  const cls = getClass(instanceOrCls);
33
33
  const propertyKey = property ?? CONSTRUCTOR_PROPERTY;
34
34
  if (typeof idx !== 'number') {
35
- DependencyRegistryIndex.registerFieldMetadata(cls, propertyKey, cfg);
35
+ DependencyRegistryIndex.registerFieldMetadata(cls, propertyKey, config);
36
36
  } else {
37
- DependencyRegistryIndex.registerParameterMetadata(cls, propertyKey, idx, cfg);
37
+ DependencyRegistryIndex.registerParameterMetadata(cls, propertyKey, idx, config);
38
38
  }
39
39
  };
40
40
  }
@@ -44,9 +44,9 @@ export function Inject(config?: InjectConfig | symbol) {
44
44
  * @augments `@travetto/schema:Method`
45
45
  * @kind decorator
46
46
  */
47
- export function InjectableFactory(config?: Partial<InjectableCandidate> | symbol) {
48
- return <T extends Class>(cls: T, property: string | symbol, descriptor: TypedPropertyDescriptor<(...args: Any[]) => Any>): void => {
49
- DependencyRegistryIndex.getForRegister(cls).registerFactory(property, fromArg(config), {
47
+ export function InjectableFactory(input?: Partial<InjectableCandidate> | symbol) {
48
+ return <T extends Class>(cls: T, property: string, descriptor: TypedPropertyDescriptor<(...args: Any[]) => Any>): void => {
49
+ DependencyRegistryIndex.getForRegister(cls).registerFactory(property, fromInput(input), {
50
50
  factory: (...params: unknown[]) => descriptor.value!.apply(cls, params),
51
51
  });
52
52
  };
@@ -1,24 +1,24 @@
1
1
  import { RegistryAdapter } from '@travetto/registry';
2
- import { Class, classConstruct, describeFunction, getAllEntries, safeAssign } from '@travetto/runtime';
2
+ import { Class, classConstruct, describeFunction, safeAssign } from '@travetto/runtime';
3
3
  import { CONSTRUCTOR_PROPERTY, SchemaRegistryIndex } from '@travetto/schema';
4
4
 
5
5
  import { InjectableConfig, getDefaultQualifier, InjectableCandidate } from '../types';
6
6
 
7
- function combineInjectableCandidates<T extends InjectableCandidate>(base: T, ...override: Partial<T>[]): typeof base {
8
- for (const o of override) {
9
- safeAssign(base, o);
7
+ function combineInjectableCandidates<T extends InjectableCandidate>(base: T, ...overrides: Partial<T>[]): typeof base {
8
+ for (const override of overrides) {
9
+ safeAssign(base, override);
10
10
  }
11
11
  return base;
12
12
  }
13
13
 
14
- function combineClasses<T extends InjectableConfig>(base: T, ...override: Partial<T>[]): typeof base {
15
- for (const o of override) {
14
+ function combineClasses<T extends InjectableConfig>(base: T, ...overrides: Partial<T>[]): typeof base {
15
+ for (const override of overrides) {
16
16
  Object.assign(base, {
17
17
  ...base,
18
- ...o,
18
+ ...override,
19
19
  candidates: {
20
20
  ...base.candidates,
21
- ...o.candidates,
21
+ ...override.candidates,
22
22
  }
23
23
  });
24
24
  }
@@ -38,7 +38,7 @@ export class DependencyRegistryAdapter implements RegistryAdapter<InjectableConf
38
38
  return combineClasses(this.#config, ...data);
39
39
  }
40
40
 
41
- registerFactory(method: string | symbol, ...data: Partial<InjectableCandidate<unknown>>[]): InjectableCandidate {
41
+ registerFactory(method: string, ...data: Partial<InjectableCandidate<unknown>>[]): InjectableCandidate {
42
42
  const { candidates } = this.register();
43
43
  candidates[method] ??= {
44
44
  class: this.#cls,
@@ -62,17 +62,16 @@ export class DependencyRegistryAdapter implements RegistryAdapter<InjectableConf
62
62
  }
63
63
 
64
64
  finalize(): void {
65
- for (const [k] of getAllEntries(this.#config.candidates)) {
66
- const v = this.#config.candidates[k];
67
- const candidateType = SchemaRegistryIndex.get(v.class).getMethodReturnType(k);
68
- v.candidateType = candidateType;
69
- v.qualifier ??= getDefaultQualifier(candidateType);
65
+ for (const method of Object.keys(this.#config.candidates)) {
66
+ const candidate = this.#config.candidates[method];
67
+ const candidateType = SchemaRegistryIndex.get(candidate.class).getMethodReturnType(method);
68
+ candidate.candidateType = candidateType;
69
+ candidate.qualifier ??= getDefaultQualifier(candidateType);
70
70
  }
71
71
  }
72
72
 
73
73
  getCandidateConfigs(): InjectableCandidate[] {
74
- const entries = getAllEntries(this.#config.candidates).map(([_, item]) => item);
75
- return entries
74
+ return Object.values(this.#config.candidates)
76
75
  .filter(item => (item.enabled ?? true) === true || (typeof item.enabled === 'function' && item.enabled()))
77
76
  .filter(item => item.method !== CONSTRUCTOR_PROPERTY || !describeFunction(item.candidateType)?.abstract);
78
77
  }
@@ -1,5 +1,5 @@
1
- import { ChangeEvent, RegistryIndex, RegistryIndexStore, Registry, RetargettingProxy } from '@travetto/registry';
2
- import { AppError, castKey, castTo, Class, describeFunction, getParentClass, hasFunction, Runtime, TypedObject, Util } from '@travetto/runtime';
1
+ import { RegistryIndex, RegistryIndexStore, Registry } from '@travetto/registry';
2
+ import { AppError, castKey, castTo, Class, describeFunction, getParentClass, hasFunction, TypedObject } from '@travetto/runtime';
3
3
  import { SchemaFieldConfig, SchemaParameterConfig, SchemaRegistryIndex } from '@travetto/schema';
4
4
 
5
5
  import { Dependency, InjectableCandidate, InjectableClassMetadata, InjectableConfig, ResolutionType } from '../types';
@@ -32,63 +32,55 @@ export class DependencyRegistryIndex implements RegistryIndex {
32
32
  return this.#instance.getCandidates<T>(candidateType);
33
33
  }
34
34
 
35
- static getCandidateTypes<T>(candidateType: Class<T>): Class<T>[] {
36
- return this.#instance.getCandidates(candidateType).map(c => c.candidateType);
37
- }
38
-
39
- static getInstances<T>(candidateType: Class<T>, predicate?: (cfg: InjectableCandidate<T>) => boolean): Promise<T[]> {
35
+ static getInstances<T>(candidateType: Class<T>, predicate?: (config: InjectableCandidate<T>) => boolean): Promise<T[]> {
40
36
  return this.#instance.getInstances<T>(candidateType, predicate);
41
37
  }
42
38
 
43
- static injectFields<T extends { constructor: Class<T> }>(o: T, cls = o.constructor): Promise<T> {
44
- return this.#instance.injectFields(cls, o, cls);
45
- }
46
-
47
- static getOptional(cls: Class): InjectableConfig | undefined {
48
- return this.#instance.store.getOptional(cls)?.get();
39
+ static injectFields<T extends { constructor: Class<T> }>(item: T, cls = item.constructor): Promise<T> {
40
+ return this.#instance.injectFields(cls, item, cls);
49
41
  }
50
42
 
51
43
  static registerClassMetadata(cls: Class, metadata: InjectableClassMetadata): void {
52
44
  SchemaRegistryIndex.getForRegister(cls).registerMetadata<InjectableClassMetadata>(MetadataSymbol, metadata);
53
45
  }
54
46
 
55
- static registerParameterMetadata(cls: Class, method: string | symbol, index: number, metadata: Dependency): void {
47
+ static registerParameterMetadata(cls: Class, method: string, index: number, metadata: Dependency): void {
56
48
  SchemaRegistryIndex.getForRegister(cls).registerParameterMetadata(method, index, MetadataSymbol, metadata);
57
49
  }
58
50
 
59
- static registerFieldMetadata(cls: Class, field: string | symbol, metadata: Dependency): void {
51
+ static registerFieldMetadata(cls: Class, field: string, metadata: Dependency): void {
60
52
  SchemaRegistryIndex.getForRegister(cls).registerFieldMetadata(field, MetadataSymbol, metadata);
61
53
  }
62
54
 
63
- #proxies = new Map<string, Map<symbol | undefined, RetargettingProxy<unknown>>>();
64
55
  #instances = new Map<Class, Map<symbol, unknown>>();
65
56
  #instancePromises = new Map<Class, Map<symbol, Promise<unknown>>>();
66
57
  #resolver = new DependencyRegistryResolver();
67
58
 
68
- #proxyInstance<T>(target: Class<unknown>, qualifier: symbol, instance: T): T {
69
- let proxy: RetargettingProxy<unknown>;
70
- const targetId = target.Ⲑid;
71
-
72
- if (!this.#proxies.has(targetId)) {
73
- this.#proxies.set(targetId, new Map());
59
+ async #resolveDependencyValue(dependency: Dependency, input: SchemaFieldConfig | SchemaParameterConfig, cls: Class): Promise<unknown> {
60
+ try {
61
+ const target = dependency.target ?? input.type;
62
+ return await this.getInstance(target, dependency.qualifier, dependency.resolution);
63
+ } catch (error) {
64
+ if (input.required?.active === false && error instanceof InjectionError && error.category === 'notfound') {
65
+ return undefined;
66
+ } else {
67
+ if (error && error instanceof Error) {
68
+ error.message = `${error.message} via=${cls.Ⲑid}[${input.name?.toString() ?? 'constructor'}]`;
69
+ }
70
+ throw error;
71
+ }
74
72
  }
73
+ }
75
74
 
76
- if (!this.#proxies.get(targetId)!.has(qualifier)) {
77
- proxy = new RetargettingProxy(instance);
78
- this.#proxies.get(targetId)!.set(qualifier, proxy);
79
- console.debug('Registering proxy', { id: target.Ⲑid, qualifier: qualifier.toString() });
80
- } else {
81
- proxy = this.#proxies.get(targetId)!.get(qualifier)!;
82
- proxy.setTarget(instance);
83
- console.debug('Updating target', {
84
- id: target.Ⲑid, qualifier: qualifier.toString(), instanceType: target.name
85
- });
86
- }
75
+ store = new RegistryIndexStore(DependencyRegistryAdapter);
76
+
77
+ /** @private */ constructor(source: unknown) { Registry.validateConstructor(source); }
87
78
 
88
- return proxy.get();
79
+ getConfig(cls: Class): InjectableConfig {
80
+ return this.store.get(cls).get();
89
81
  }
90
82
 
91
- #addClass(cls: Class, forceCreate: boolean = false): void {
83
+ onCreate(cls: Class): void {
92
84
  const adapter = this.store.get(cls);
93
85
 
94
86
  for (const config of adapter.getCandidateConfigs()) {
@@ -97,55 +89,17 @@ export class DependencyRegistryIndex implements RegistryIndex {
97
89
  const hasParentBase = (parentConfig || (parentClass && !!describeFunction(parentClass)?.abstract));
98
90
  const baseParent = hasParentBase ? parentClass : undefined;
99
91
  this.#resolver.registerClass(config, baseParent);
100
- if (config.autoInject || forceCreate) {
101
- // Don't wait
102
- Util.queueMacroTask().then(() => {
103
- this.getInstance(config.candidateType, config.qualifier);
104
- });
105
- }
106
- }
107
- }
108
-
109
- #removeClass(cls: Class): void {
110
- if (this.#instances.has(cls)) {
111
- for (const [qualifier, config] of this.#resolver.getContainerEntries(cls)) {
112
- try {
113
- this.destroyInstance(config.candidateType, qualifier);
114
- } catch { }
115
- }
116
92
  }
117
93
  }
118
94
 
119
-
120
- async #resolveDependencyValue(dependency: Dependency, input: SchemaFieldConfig | SchemaParameterConfig, src: Class): Promise<unknown> {
121
- try {
122
- const target = dependency.target ?? input.type;
123
- return await this.getInstance(target, dependency.qualifier, dependency.resolution);
124
- } catch (err) {
125
- if (input.required?.active === false && err instanceof InjectionError && err.category === 'notfound') {
126
- return undefined;
127
- } else {
128
- if (err && err instanceof Error) {
129
- err.message = `${err.message} via=${src.Ⲑid}[${input.name?.toString() ?? 'constructor'}]`;
95
+ // Setup instances after change set complete
96
+ onChangeSetComplete(classes: Class[]): void {
97
+ for (const cls of classes) {
98
+ const adapter = this.store.get(cls);
99
+ for (const config of adapter.getCandidateConfigs()) {
100
+ if (config.autoInject) {
101
+ this.getInstance(config.candidateType, config.qualifier);
130
102
  }
131
- throw err;
132
- }
133
- }
134
- }
135
-
136
- store = new RegistryIndexStore(DependencyRegistryAdapter);
137
-
138
- getConfig(cls: Class): InjectableConfig {
139
- return this.store.get(cls).get();
140
- }
141
-
142
- process(events: ChangeEvent<Class>[]): void {
143
- for (const ev of events) {
144
- if ('prev' in ev) {
145
- this.#removeClass(ev.prev);
146
- }
147
- if ('curr' in ev) {
148
- this.#addClass(ev.curr, 'prev' in ev);
149
103
  }
150
104
  }
151
105
  }
@@ -154,15 +108,15 @@ export class DependencyRegistryIndex implements RegistryIndex {
154
108
  * Get all available candidates for a given type
155
109
  */
156
110
  getCandidates<T>(candidateType: Class<T>): InjectableCandidate<T>[] {
157
- return this.#resolver.getCandidateEntries(candidateType).map(([_, x]) => castTo<InjectableCandidate<T>>(x));
111
+ return this.#resolver.getCandidateEntries(candidateType).map(([_, candidate]) => castTo<InjectableCandidate<T>>(candidate));
158
112
  }
159
113
 
160
114
  /**
161
115
  * Get candidate instances by target type, with an optional filter
162
116
  */
163
- getInstances<T>(candidateType: Class<T>, predicate?: (cfg: InjectableCandidate<T>) => boolean): Promise<T[]> {
164
- const inputs = this.getCandidates<T>(candidateType).filter(x => !predicate || predicate(x));
165
- return Promise.all(inputs.map(l => this.getInstance<T>(l.class, l.qualifier)));
117
+ getInstances<T>(candidateType: Class<T>, predicate?: (config: InjectableCandidate<T>) => boolean): Promise<T[]> {
118
+ const inputs = this.getCandidates<T>(candidateType).filter(candidate => !predicate || predicate(candidate));
119
+ return Promise.all(inputs.map(candidate => this.getInstance<T>(candidate.class, candidate.qualifier)));
166
120
  }
167
121
 
168
122
  /**
@@ -185,13 +139,13 @@ export class DependencyRegistryIndex implements RegistryIndex {
185
139
  const inputs = SchemaRegistryIndex.getOptional(candidateType)?.getFields() ?? {};
186
140
 
187
141
  const promises = TypedObject.entries(inputs)
188
- .filter(([k, input]) => readMetadata(input) !== undefined && (input.access !== 'readonly' && instance[castKey(k)] === undefined))
189
- .map(async ([k, input]) => [k, await this.#resolveDependencyValue(readMetadata(input) ?? {}, input, srcClass)] as const);
142
+ .filter(([key, input]) => readMetadata(input) !== undefined && (input.access !== 'readonly' && instance[castKey(key)] === undefined))
143
+ .map(async ([key, input]) => [key, await this.#resolveDependencyValue(readMetadata(input) ?? {}, input, srcClass)] as const);
190
144
 
191
145
  const pairs = await Promise.all(promises);
192
146
 
193
- for (const [k, v] of pairs) {
194
- instance[castKey(k)] = castTo(v);
147
+ for (const [key, value] of pairs) {
148
+ instance[castKey(key)] = castTo(value);
195
149
  }
196
150
  return instance;
197
151
  }
@@ -217,12 +171,12 @@ export class DependencyRegistryIndex implements RegistryIndex {
217
171
  SchemaRegistryIndex.get(targetType).getMetadata<InjectableClassMetadata>(MetadataSymbol) : undefined;
218
172
 
219
173
  // Run post constructors
220
- for (const op of Object.values(metadata?.postConstruct ?? {})) {
221
- await op(inst);
174
+ for (const operation of Object.values(metadata?.postConstruct ?? {})) {
175
+ await operation(inst);
222
176
  }
223
177
 
224
178
  // Proxy if necessary
225
- return Runtime.dynamic ? this.#proxyInstance(targetType, qualifier, inst) : inst;
179
+ return inst;
226
180
  }
227
181
 
228
182
  /**
@@ -250,10 +204,10 @@ export class DependencyRegistryIndex implements RegistryIndex {
250
204
  const instance = await instancePromise;
251
205
  this.#instances.get(target)!.set(qualifier, instance);
252
206
  return instance;
253
- } catch (err) {
207
+ } catch (error) {
254
208
  // Clear it out, don't save failed constructions
255
209
  this.#instancePromises.get(target)!.delete(qualifier);
256
- throw err;
210
+ throw error;
257
211
  }
258
212
  }
259
213
 
@@ -273,7 +227,6 @@ export class DependencyRegistryIndex implements RegistryIndex {
273
227
  this.#instancePromises.get(target)?.delete(qualifier);
274
228
 
275
229
  // May not exist
276
- this.#proxies.get(target.Ⲑid)?.get(qualifier)?.setTarget(null);
277
230
  console.debug('On uninstall', { id: target, qualifier: qualifier.toString(), classId: target });
278
231
  }
279
232
  }
@@ -6,11 +6,11 @@ import { InjectionError } from '../error';
6
6
 
7
7
  type Resolved<T> = { candidate: InjectableCandidate<T>, qualifier: symbol, target: Class };
8
8
 
9
- function setInMap<T>(map: Map<Class, Map<typeof key, T>>, src: Class, key: symbol | string, dest: T): void {
10
- if (!map.has(src)) {
11
- map.set(src, new Map());
9
+ function setInMap<T>(map: Map<Class, Map<typeof key, T>>, cls: Class, key: symbol | string, dest: T): void {
10
+ if (!map.has(cls)) {
11
+ map.set(cls, new Map());
12
12
  }
13
- map.get(src)!.set(key, dest);
13
+ map.get(cls)!.set(key, dest);
14
14
  }
15
15
 
16
16
  export class DependencyRegistryResolver {
@@ -38,15 +38,17 @@ export class DependencyRegistryResolver {
38
38
  if (qualifiers.has(PrimaryCandidateSymbol)) {
39
39
  return PrimaryCandidateSymbol;
40
40
  } else {
41
- const filtered = resolved.filter(x => !!x).filter(x => this.#defaultSymbols.has(x));
41
+ const filtered = resolved
42
+ .filter(qualifier => !!qualifier)
43
+ .filter(qualifier => this.#defaultSymbols.has(qualifier));
42
44
  // If there is only one default symbol
43
45
  if (filtered.length === 1) {
44
46
  return filtered[0];
45
47
  } else if (filtered.length > 1) {
46
48
  // If dealing with sub types, prioritize exact matches
47
49
  const exact = this.getCandidateEntries(type)
48
- .map(([_, x]) => x)
49
- .filter(x => x.candidateType === type);
50
+ .map(([_, candidate]) => candidate)
51
+ .filter(candidate => candidate.candidateType === type);
50
52
 
51
53
  if (exact.length === 1) {
52
54
  return exact[0].qualifier;
package/src/types.ts CHANGED
@@ -32,7 +32,7 @@ export interface InjectableCandidate<T = unknown> {
32
32
  /**
33
33
  * Method that is injectable on class
34
34
  */
35
- method: string | symbol;
35
+ method: string;
36
36
  /**
37
37
  * Method handle
38
38
  */
@@ -74,7 +74,7 @@ export interface InjectableConfig<T = unknown> {
74
74
  /**
75
75
  * Candidates that are injectable
76
76
  */
77
- candidates: Record<string | symbol, InjectableCandidate>;
77
+ candidates: Record<string, InjectableCandidate>;
78
78
  }
79
79
 
80
80
  export function getDefaultQualifier(cls: Class): symbol {
@@ -85,5 +85,5 @@ export function getDefaultQualifier(cls: Class): symbol {
85
85
  export const PrimaryCandidateSymbol = Symbol();
86
86
 
87
87
  export type InjectableClassMetadata = {
88
- postConstruct: Record<string | symbol, (<T>(inst: T) => Promise<void>)>;
88
+ postConstruct: Record<string, (<T>(inst: T) => Promise<void>)>;
89
89
  };