UNPKG

rsdi

Version:

TypeScript dependency injection container. Strong types without decorators.

67 lines (66 loc) 3.12 kB
import { type DenyInputKeys, type Factory, type IDIContainer, type ResolvedDependencies, type StringLiteral } from './types.js'; /** * Dependency injection container */ export declare class DIContainer<ContainerResolvers extends ResolvedDependencies = {}> { private context; private resolvedDependencies; private resolvers; /** * Adds new dependency resolver to the container. If dependency with given name already exists it will throw an error. * Use update method instead. It will override existing dependency. * @param name * @param resolver */ add<N extends string, R extends Factory<ContainerResolvers>>(name: StringLiteral<DenyInputKeys<N, keyof ContainerResolvers>>, resolver: R): IDIContainer<ContainerResolvers & { [n in N]: ReturnType<R>; }>; /** * Extends container with given function. It will pass container as an argument to the function. * Function should return new container with extended resolvers. * It is useful when you want to split your container into multiple files. * You can create a file with resolvers and extend container with it. * You can also use it to create multiple containers with different resolvers. * * For example: * * const container = new DIContainer() * .extend(addValidators) * * export type DIWithValidators = ReturnType<typeof addValidators>; * export const addValidators = (container: DIWithDataAccessors) => { * return container * .add('myValidatorA', ({ a, b, c }) => new MyValidatorA(a, b, c)) * .add('myValidatorB', ({ a, b, c }) => new MyValidatorB(a, b, c)); * }; * @param diConfigurationFactory */ extend<Extension extends ResolvedDependencies, FactoryFunction extends (container: IDIContainer<ContainerResolvers>) => IDIContainer<ContainerResolvers & Extension>>(diConfigurationFactory: FactoryFunction): IDIContainer<ContainerResolvers & Extension>; /** * Resolve dependency by name. Alternatively you can use property access to resolve dependency. * For example: const { a, b } = container; * @param dependencyName */ get<Name extends keyof ContainerResolvers>(dependencyName: Name): ContainerResolvers[Name]; /** * Checks if dependency with given name exists * @param name */ has(name: string): boolean; /** * Updates existing dependency resolver. If dependency with given name does not exist it will throw an error. * In most cases you don't need to override dependencies and should use add method instead. This approach will * help you to avoid overriding dependencies by mistake. * * You may want to override dependency if you want to mock it in tests. * @param name * @param resolver */ update<N extends keyof ContainerResolvers, R extends Factory<ContainerResolvers>>(name: StringLiteral<N>, resolver: R): IDIContainer<{ [n in N]: ReturnType<R>; } & { [P in Exclude<keyof ContainerResolvers, N>]: ContainerResolvers[P]; }>; private setValue; private toContainer; }