export const DEPENDENCY_KEYS_METADATA_KEY = 'extollo:di:dependencies:ctor' export const DEPENDENCY_KEYS_PROPERTY_METADATA_KEY = 'extollo:di:dependencies:properties' export const DEPENDENCY_KEYS_SERVICE_TYPE_KEY = 'extollo:di:service_type' /** * Interface that designates a particular value as able to be constructed. */ export interface Instantiable { new(...args: any[]): T } /** * Returns true if the given value is instantiable. * @param what */ export function isInstantiable(what: unknown): what is Instantiable { return ( Boolean(what) && (typeof what === 'object' || typeof what === 'function') && (what !== null) && 'constructor' in what && typeof what.constructor === 'function' ) } /** * Returns true if the given value is instantiable and, once instantiated, * will create an instance of the given static class. * @param what * @param type */ export function isInstantiableOf(what: unknown, type: StaticClass): what is Instantiable { return isInstantiable(what) && what.prototype instanceof type } /** * Type that identifies a value as a static class, even if it is not instantiable. */ export type StaticClass = Function & {prototype: T} & { new (...args: TCtorParams) : T } & T2 // eslint-disable-line @typescript-eslint/ban-types /** * Type that identifies a value as a static class that instantiates to itself */ export type StaticInstantiable = StaticClass> /** * Returns true if the parameter is a static class. * @param something */ export function isStaticClass(something: unknown): something is StaticClass { return typeof something === 'function' && typeof something.prototype !== 'undefined' } /** * Type used to represent a value that can identify a factory in the container. */ export type DependencyKey = Instantiable | StaticClass | string /** * A DependencyKey, but typed */ export type TypedDependencyKey = Instantiable | StaticClass | string /** * Interface used to store dependency requirements by their place in the injectable * target's parameters. */ export interface DependencyRequirement { paramIndex: number, key: DependencyKey, overridden: boolean, } /** * Interface used to store dependency requirements by the class property they should * be injected into. */ export interface PropertyDependency { key: DependencyKey, property: string | symbol, debug?: boolean, } /** * Interface used to keep track of singleton factory values, by their dependency key. */ export interface InstanceRef { key: DependencyKey, value: any, } /** * Interface used to keep track of the injection type of a class. */ export interface InjectionType { type: 'named' | 'singleton', name?: string, }