From 31de73db0044b5a44bec390f3f76843052742855 Mon Sep 17 00:00:00 2001 From: "Max P." Date: Wed, 2 Apr 2025 22:18:23 +0200 Subject: [PATCH] docs(api): add full JSDoc for all `inject()` overloads with examples --- src/functions/inject.ts | 145 ++++++++++++++++++++++++++++++++++------ 1 file changed, 126 insertions(+), 19 deletions(-) diff --git a/src/functions/inject.ts b/src/functions/inject.ts index 192769e..d2214de 100644 --- a/src/functions/inject.ts +++ b/src/functions/inject.ts @@ -9,34 +9,141 @@ import { Identifier } from '../types/Identifier.js'; import { InitDelegate } from '../types/InitDelegate.js'; /** - * A function to inject a dependency from a DI (Dependency Injection) container into a variable. - * @template T The type of the dependency to be injected. - * @template U The type of the property to be injected. - * @param identifier The identifier used to resolve the class in the DI container. - * @see {@link Identifier} for more information on identifiers. - * @param init Optional an initializer function to transform the dependency before injection - * or true to instantiate the dependency if it has a constructor. - * @see {@link InitDelegate} for more information on initializer functions. - * @param isNecessary If true, throws an error if the dependency is not found. - * @returns The resolved dependency or undefined if the dependency is not necessary - * and not found, or throws an error if the dependency is necessary and not found. - * @throws **Only throws errors if the dependency is necessary.** + * Resolves a dependency by its identifier without initialization or instantiation. + * @template T The expected type of the dependency. + * @param identifier The identifier used to resolve the dependency from the container. + * @returns The resolved dependency. * @throws A {@link DependencyResolutionError} if the dependency is not found. - * @throws A {@link InjectorError} if an error occurs during the injection process. - * @throws A {@link NoInstantiationMethodError} if the dependency does not have a constructor. - * @throws An {@link InitializationError} if an error occurs during the initialization process. * @example * ```ts - * let myDependency = inject('MyDependencyIdentifier'); + * const logger = inject('Logger'); * ``` + */ +export function inject(identifier: Identifier): T; + +/** + * Resolves and instantiates a dependency using its constructor. + * @template T The expected class type of the dependency. + * @param identifier The identifier used to resolve the dependency from the container. + * @param shouldInit Set to `true` to instantiate the dependency after resolution. + * @returns The resolved and instantiated dependency. + * @throws A {@link DependencyResolutionError} if the dependency is not found. + * @throws A {@link NoInstantiationMethodError} if the dependency has no constructor. + * @throws An {@link InitializationError} if instantiation fails. * @example * ```ts - * let logger = inject('ILogger_', (x: ILogger_) => x.getLogger('Tags'), false); + * const instance = inject('Service', true); + * ``` + */ +export function inject(identifier: Identifier, shouldInit: true): T; + +/** + * Resolves and instantiates a dependency using its constructor, optionally failing silently. + * @template T The expected class type of the dependency. + * @param identifier The identifier used to resolve the dependency from the container. + * @param shouldInit Set to `true` to instantiate the dependency. + * @param isNecessary If `false`, resolution or instantiation errors return `undefined` instead of throwing. + * @returns The resolved and instantiated dependency, or `undefined` if resolution or instantiation fails. + * @example + * ```ts + * const instance = inject('OptionalService', true, false); + * if (instance) instance.doSomething(); + * ``` + */ +export function inject( + identifier: Identifier, + shouldInit: true, + isNecessary: false, +): T | undefined; + +/** + * Resolves a dependency without instantiating it, optionally failing silently. + * @template T The expected type of the dependency. + * @param identifier The identifier used to resolve the dependency from the container. + * @param shouldInit Set to `false` to skip instantiation. + * @param isNecessary If `false`, resolution errors return `undefined` instead of throwing. + * @returns The resolved dependency, or `undefined` if not found. + * @example + * ```ts + * const config = inject('Config', false, false) ?? getDefaultConfig(); + * ``` + */ +export function inject( + identifier: Identifier, + shouldInit: false, + isNecessary: false, +): T | undefined; + +/** + * Resolves a dependency and applies a custom initializer function to transform the result. + * @template T The original dependency type. + * @template U The final return type after initialization. + * @param identifier The identifier used to resolve the dependency. + * @param init A function to transform or initialize the dependency. + * @returns The transformed dependency. + * @throws A {@link DependencyResolutionError} if the dependency is not found. + * @throws An {@link InitializationError} if the initializer throws. + * @example + * ```ts + * const client = inject('Api', (api) => api.getClient()); * ``` */ export function inject( identifier: Identifier, - init?: InitDelegate | true, + init: InitDelegate, +): U; + +/** + * Resolves a dependency and applies a custom initializer function, optionally failing silently. + * @template T The original dependency type. + * @template U The final return type after initialization. + * @param identifier The identifier used to resolve the dependency. + * @param init A function to transform or initialize the dependency. + * @param isNecessary If `false`, resolution or initializer errors return `undefined` instead of throwing. + * @returns The transformed dependency, or `undefined` if resolution or initialization fails. + * @example + * ```ts + * const db = inject('Database', (d) => d.getPool(), false); + * if (db) db.query('SELECT * FROM users'); + * ``` + */ +export function inject( + identifier: Identifier, + init: InitDelegate, + isNecessary: false, +): U | undefined; + +/** + * A function to inject a dependency from a DI (Dependency Injection) container into a variable. + * This is the actual implementation that handles all overload variants. + * @template T The original dependency type. + * @template U The final return type after optional initialization or transformation. + * @param identifier The identifier used to resolve the dependency. + * @see {@link Identifier} for more information on identifiers. + * @param init Optional: either `true` to instantiate via constructor, `false` to skip, or a function to transform the dependency. + * @see {@link InitDelegate} for more information on initializer functions. + * @param isNecessary If `true`, throws on failure; if `false`, returns `undefined` on resolution or initialization errors. + * @returns The resolved dependency or result of initialization, or `undefined` if not necessary and resolution fails. + * @throws A {@link DependencyResolutionError} if the dependency is not found (and necessary). + * @throws A {@link NoInstantiationMethodError} if instantiation is requested but no constructor exists. + * @throws An {@link InitializationError} if the initializer throws an error. + * @throws A {@link InjectorError} for unknown errors during resolution or transformation. + * @example + * ```ts + * const service = inject('Service'); + * ``` + * @example + * ```ts + * const instance = inject('Service', true); + * ``` + * @example + * ```ts + * const logger = inject('ILogger_', (x) => x.getLogger('Module'), false); + * ``` + */ +export function inject( + identifier: Identifier, + init?: InitDelegate | true | false, isNecessary = true, ): T | U | undefined { let instance: T | U | undefined; @@ -56,7 +163,7 @@ export function inject( ? (): U => new dependency() as U : undefined; - if (init == null) instance = dependency; + if (init == null || init === false) instance = dependency; else if (initFunction != null) instance = tryAndCatch( initFunction,