dioma
Version:
Elegant dependency injection container for vanilla JavaScript and TypeScript
107 lines (81 loc) • 4.08 kB
text/typescript
declare type AnyDescriptor = TokenValueDescriptor<any> | TokenFactoryDescriptor<any> | TokenClassDescriptor<any>;
declare type ArgsOf<T, C = TokenType<T, T>> = C extends Newable ? OptionalArgs<ConstructorParameters<C>> : any[];
export declare class ArgumentsError extends Error {
constructor(scope: string, className: string);
}
export declare class AsyncDependencyCycleError extends Error {
constructor();
}
declare type BaseDescriptor = {
beforeInject?: (container: Container, descriptor: AnyDescriptor, args: any[]) => any;
beforeCreate?: (container: Container, descriptor: AnyDescriptor, args: any[]) => any;
};
export declare const childContainer: (name?: string) => Container;
export declare class Container {
private parentContainer;
name?: string | undefined;
private instances;
private resolutionContainer;
private resolutionSet;
private pendingPromiseMap;
private tokenDescriptorMap;
private resolutionsLoopCounter;
constructor(parentContainer?: Container | null, name?: string | undefined);
childContainer: (name?: string) => Container;
$getInstance(descriptor: TokenClassDescriptor<any>, args?: any[], cache?: boolean): any;
private getTokenDescriptor;
private injectImpl;
inject: <T extends TokenOrClass, Args extends ArgsOf<T>>(cls: T, ...args: Args) => InstanceOf<T>;
injectAsync: <T extends TokenOrClass, Args extends ArgsOf<T>>(cls: T, ...args: Args) => Promise<InstanceOf<T>>;
waitAsync: () => Promise<void>;
register<T extends Token<any>>(descriptor: TokenValueDescriptor<T>): void;
register<T extends Token<any>>(descriptor: TokenFactoryDescriptor<T>): void;
register<T extends Token<any>>(descriptor: TokenClassDescriptor<T>): void;
unregister: (token: TokenOrClass) => void;
reset: () => void;
}
export declare class DependencyCycleError extends Error {
constructor();
}
export declare const globalContainer: Container;
export declare const inject: <T extends TokenOrClass, Args extends ArgsOf<T, T extends Token<infer U> ? U : T>>(cls: T, ...args: Args) => InstanceOf<T, T extends Token<infer U> ? U : T>;
export declare type Injectable<C extends I, I extends ScopedClass = ScopedClass> = InstanceType<I>;
export declare const injectAsync: <T extends TokenOrClass, Args extends ArgsOf<T, T extends Token<infer U> ? U : T>>(cls: T, ...args: Args) => Promise<InstanceOf<T, T extends Token<infer U> ? U : T>>;
declare type InstanceOf<T, C = TokenType<T, T>> = C extends Newable ? InstanceType<C> : C;
declare type Newable<T = any> = new (...args: any[]) => T;
declare type OptionalArgs<T, R = Required<T>> = R extends readonly [...infer Rest, infer Last] ? R | OptionalArgs<Rest> : [];
export declare interface ScopedClass {
new (...args: any[]): any;
scope: ScopeHandler;
}
declare type ScopeHandler = (cls: any, args: any[], container: Container, resolutionContainer: Container) => any;
export declare class Scopes {
static Singleton(): ScopeHandler;
static Transient(): ScopeHandler;
static Container(): ScopeHandler;
static Resolution(): ScopeHandler;
static Scoped: typeof Scopes.Container;
}
export declare class Token<T> {
readonly name?: string | undefined;
constructor(name?: string | undefined);
}
export declare type TokenClassDescriptor<T extends Token<any>> = BaseDescriptor & {
token?: T;
class: Newable<TokenType<T>>;
scope?: ScopeHandler;
};
export declare type TokenFactoryDescriptor<T extends Token<any>> = BaseDescriptor & {
token: T;
factory: (container: Container, ...args: any[]) => TokenType<T>;
};
export declare class TokenNotRegisteredError extends Error {
constructor();
}
declare type TokenOrClass = Token<any> | ScopedClass;
declare type TokenType<T, R = any> = T extends Token<infer U> ? U : R;
export declare type TokenValueDescriptor<T extends Token<any>> = BaseDescriptor & {
token: T;
value: TokenType<T>;
};
export { }