/** * Base type interfaces for dependency injection. * * These types define the core abstractions for DI tokens and class references. */ /** * Constructor type for a concrete class that produces instances of T. * * Useful anywhere a factory/DI container expects a class reference that can be * `new`-ed. For example: `getProvider(UserRepo as Type)`. */ export interface Type extends Function { new (...args: any[]): T; } /** * Function type that returns T or Promise. * Used for factory functions in DI. */ export type FuncType = (...args: any[]) => T | Promise; /** * Partial record mapping stage names to arrays of types. * Used for multi-stage initialization patterns. */ export type PartialStagesType = Partial>; /** * Empty Constructor type for a concrete class that produces instances of T. * * Useful for classes that can be instantiated without arguments. */ export interface CtorType extends Function { new (): T; } /** * Constructor type with arbitrary arguments. */ export type Ctor = new (...args: any[]) => T; /** * Shape of an abstract class (or interface-like constructor) whose instances * cannot be created directly but still expose a prototype of T. * * This is handy when accepting references that may point at abstract bases * instead of concrete implementors. */ export interface Abstract extends Function { prototype: T; } /** * A reference token that may be used to look up or identify a dependency. * * Typical usages: * - string | symbol: named tokens (e.g., provider IDs like "provider:redis"). * - Type: a concrete class constructor (can be instantiated). * - Abstract: an abstract base reference (resolved to a concrete impl). * - Function: generic function references when needed. */ export type Reference = string | symbol | Type | Abstract | Function; /** * A DI token that can be either a class constructor or a logical reference. * This is the primary type for identifying dependencies in the DI system. */ export type Token = Type | Reference; /** * Provider definition using a class implementation. */ export interface ClassType { provide: Reference; useClass: Type; } /** * Provider definition using a static value. */ export interface ValueType { provide: Reference; useValue: Provide; } /** * Abstract class token type for dependency references. */ export type ClassToken = abstract new (...a: any) => T; /** * Resolve a single token to its instance type. */ type ResolveToken = T extends ClassToken ? R : T extends symbol & { readonly __di_type?: infer R; } ? R : never; /** * Resolve a tuple of tokens to their instance types. */ type ResolveTokens = { [K in keyof Tokens]: Tokens[K] extends Token ? R : ResolveToken; }; /** * Strip readonly from tuple type for rest parameters. */ type Mutable = { -readonly [K in keyof T]: T[K]; }; /** * Factory provider definition with dependency injection. * * @example * ```typescript * const factory: FactoryType = { * provide: Database, * inject: () => [Config, Logger] as const, * useFactory: (config, logger) => new Database(config, logger), * }; * ``` */ export interface FactoryType { provide: Reference; inject: () => Tokens; useFactory: (...args: Mutable>) => Provide | Promise; } /** * Utility type to make specific keys required. */ export type RequiredByKey = T & Required>; export {};