Skip to content

Commit

Permalink
Attempting to type Inject.Container
Browse files Browse the repository at this point in the history
  • Loading branch information
mojocakes committed Oct 15, 2021
1 parent d2ce1f0 commit 969c04d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 21 deletions.
27 changes: 15 additions & 12 deletions packages/botox/src/Botox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,33 @@ export const DEFAULT_DEPENDENCY_CONFIG: Inject.TDependencyConfig = {

export const INJECTABLES_PROPERTY = '__injected_arguments';

export class Container implements Inject.IContainer {
protected dependencies: Inject.TDependencyMap = {};
export class Container<TDepList extends Record<Inject.TDependencyIdentifier, any>> implements Inject.IContainer<TDepList> {
protected dependencies: Inject.TDependencyMap<any> = {};

readonly parent: null | Inject.IContainer;
readonly parent: null | Inject.IContainer<any>;

constructor(parent?: Inject.IContainer) {
constructor(parent?: Inject.IContainer<any>) {
this.parent = parent || null;
}

get<T extends Inject.TInjectable = any>(identifier: Inject.TDependencyIdentifier): undefined | T {
public get(identifier: keyof TDepList)
// : TDepList[keyof TDepList] // TODO: Commenting this out = "any", leaving it in created a union type
{
const dep = this.dependencies[identifier];

if (!dep && this.parent) {
return this.parent.get(identifier);
}

if (!dep) {
return;
throw new Error(`No dependency registered with key "${identifier}"`);
}

return this.prepareReturnedValue(dep.value, dep.config);
}

register(
identifier: Inject.TDependencyIdentifier,
public register(
identifier: keyof TDepList,
value: Inject.TInjectable,
config: Inject.TDependencyConfig = DEFAULT_DEPENDENCY_CONFIG,
): void {
Expand All @@ -46,12 +48,12 @@ export class Container implements Inject.IContainer {
};
}

unregister(identifier: Inject.TDependencyIdentifier): void {
public unregister(identifier: keyof TDepList): void {
delete this.dependencies[identifier];
}

public clone(): Inject.IContainer {
return new Container(this);
public clone(): Inject.IContainer<any> {
return new Container<TDepList>(this);
}

protected prepareReturnedValue(value: any, config: Inject.TDependencyConfig): any {
Expand All @@ -62,11 +64,12 @@ export class Container implements Inject.IContainer {
return value;
}

protected prepareStoredValue(value: any, config: Inject.TDependencyConfig, identifier: Inject.TDependencyIdentifier): any {
protected prepareStoredValue(value: any, config: Inject.TDependencyConfig, identifier: keyof TDepList): any {
if (config.cache && config.construct) {
if (!this.isConstructor(value)) {
throw new Error(`Container error: provided value for "${identifier}" is not newable.`);
}

return new value;
}

Expand Down
18 changes: 9 additions & 9 deletions packages/types/src/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ import { Generic } from "./generic";

export namespace Inject {
// The dependency injection container.
export interface IContainer {
export interface IContainer<TDepList extends Record<Inject.TDependencyIdentifier, any>> {
/**
* Retrieves a service or value from the container.
*
* @param {TDependencyIdentifier} identifier
* @param {keyof TDepList} identifier
* @returns {undefined | T}
*/
get<T extends TInjectable = any>(identifier: TDependencyIdentifier): undefined | T;
get(identifier: keyof TDepList): TDepList[keyof TDepList];

/**
* Registers a service or value with the container.
*
* @param {TDependencyIdentifier=} identifier
* @param {keyof TDepList=} identifier
* @param {TInjectable} value
* @param {TDependencyConfig=} config
* @returns {void}
*/
register(
identifier: TDependencyIdentifier,
identifier: keyof TDepList,
value: TInjectable,
config?: TDependencyConfig,
): void;
Expand All @@ -33,15 +33,15 @@ export namespace Inject {
*/
// resolve<T = any>(injectable: TInjectable): T;

readonly parent: null | IContainer;
readonly parent: null | IContainer<any>;

clone(): IContainer;
clone(): IContainer<any>;
}

export type TInjectable = Generic.TConstructor<any>;

export type TInjectableConfig = {
container: IContainer;
container: IContainer<any>;
};

export type TDependencyIdentifier = string | number;
Expand All @@ -53,5 +53,5 @@ export namespace Inject {

export type TDependency<T extends Object = any> = T | Generic.TConstructor<T>;

export type TDependencyMap = Record<TDependencyIdentifier, { value: TDependency, config: TDependencyConfig }>;
export type TDependencyMap<TIdentifiers extends TDependencyIdentifier = TDependencyIdentifier> = Record<TIdentifiers, { value: TDependency, config: TDependencyConfig }>;
}

0 comments on commit 969c04d

Please sign in to comment.