Types
This document describes the type definitions used in Vercube's dependency injection system. Understanding these types is crucial for working effectively with the DI system.
Core Types
ServiceKey<T>
A type that represents a service identifier. It can be a constructor function, an interface, or a string.
type ServiceKey<T> = Constructor<T> | Interface<T> | string;
Examples
// Using a class
class UserService {}
const userServiceKey: ServiceKey<UserService> = UserService;
// Using an interface
interface ILogger {
info(message: string): void;
}
const loggerKey: ServiceKey<ILogger> = 'ILogger';
// Using a string
const configKey: ServiceKey<Config> = 'AppConfig';
ServiceValue<T>
A type that represents a service implementation. It can be a constructor function, a factory function, or an instance.
type ServiceValue<T> = Constructor<T> | Factory<T> | T;
Examples
// Using a class
class ConsoleLogger implements ILogger {}
const loggerValue: ServiceValue<ILogger> = ConsoleLogger;
// Using a factory function
const loggerFactory: ServiceValue<ILogger> = () => new ConsoleLogger();
// Using an instance
const loggerInstance: ServiceValue<ILogger> = new ConsoleLogger();
Constructor<T>
A type that represents a constructor function for a class.
type Constructor<T> = new (...args: any[]) => T;
Examples
class UserService {
@Inject(Logger)
private logger!: Logger;
}
const UserServiceConstructor: Constructor<UserService> = UserService;
Factory<T>
A type that represents a factory function that creates a service instance.
type Factory<T> = () => T;
Examples
const createLogger: Factory<Logger> = () => new ConsoleLogger();
Service Definition Types
ServiceDef<T>
A type that represents a service definition, including its implementation and scope.
interface ServiceDef<T> {
key: ServiceKey<T>;
value: ServiceValue<T>;
scope: ServiceScope;
}
ServiceScope
An enum that defines the scope of a service.
enum ServiceScope {
Singleton,
Transient,
Instance,
Mock
}
Examples
const loggerDef: ServiceDef<ILogger> = {
key: 'ILogger',
value: ConsoleLogger,
scope: ServiceScope.Singleton
};
Container Options
ContainerOptions
An interface that defines the configuration options for a container.
interface ContainerOptions {
autoBindInjectable?: boolean;
strictMode?: boolean;
}
Examples
const options: ContainerOptions = {
autoBindInjectable: true,
strictMode: false
};
Metadata Types
DependencyMetadata
An interface that represents the metadata for a dependency.
interface DependencyMetadata {
key: ServiceKey<any>;
optional: boolean;
}
Examples
const loggerMetadata: DependencyMetadata = {
key: 'ILogger',
optional: false
};
ClassMetadata
An interface that represents the metadata for a class.
interface ClassMetadata {
dependencies: DependencyMetadata[];
initMethods: string[];
}
Examples
const userServiceMetadata: ClassMetadata = {
dependencies: [
{ key: 'ILogger', optional: false },
{ key: 'UserRepository', optional: false }
],
initMethods: ['initialize']
};
Utility Types
Interface<T>
A type that represents an interface.
type Interface<T> = { [P in keyof T]: T[P] };
Examples
interface ILogger {
info(message: string): void;
}
const LoggerInterface: Interface<ILogger> = {
info: (message: string) => {}
};
InjectableClass<T>
A type that represents a class that can be injected.
type InjectableClass<T> = Constructor<T> & {
__injectable?: boolean;
};
Examples
class UserService {}
const InjectableUserService: InjectableClass<UserService> = UserService;
Type Guards
isConstructor(value: any): value is Constructor<any>
A type guard that checks if a value is a constructor function.
function isConstructor(value: any): value is Constructor<any> {
return typeof value === 'function' && value.prototype && value.prototype.constructor === value;
}
isFactory(value: any): value is Factory<any>
A type guard that checks if a value is a factory function.
function isFactory(value: any): value is Factory<any> {
return typeof value === 'function' && !isConstructor(value);
}
Examples
Service Registration with Types
// Define interfaces
interface ILogger {
info(message: string): void;
}
interface IUserRepository {
findById(id: string): Promise<User>;
}
// Define implementations
class ConsoleLogger implements ILogger {
info(message: string): void {
console.log(message);
}
}
class UserRepository implements IUserRepository {
async findById(id: string): Promise<User> {
// Implementation
}
}
// Register services with proper typing
container.bind<ILogger>('ILogger', ConsoleLogger);
container.bind<IUserRepository>('IUserRepository', UserRepository);
// Use services with type safety
class UserService {
@Inject('ILogger')
private logger!: ILogger;
@Inject('IUserRepository')
private userRepository!: IUserRepository;
}
Type-Safe Service Resolution