{"id":12237,"library":"typescript-ioc","title":"TypeScript IoC Container","description":"typescript-ioc is a lightweight, annotation-based dependency injection (DI) container specifically designed for TypeScript applications. It allows developers to manage dependencies using decorators like `@Inject`, simplifying object graph creation and promoting modular design. The library is currently stable at version 3.2.2, with the 3.x series being actively maintained through frequent patch and minor releases. Key differentiators include its small footprint, ease of use with TypeScript decorators, and broad environmental support including Node.js, browsers, and React Native. It provides features such as different scopes (Singleton, Request, Local), factory creation, and configuration capabilities, making it suitable for both simple and complex application architectures where inversion of control is desired. A notable change in the 3.x series was the discontinuation of support for ES5 runtimes, requiring modern JavaScript environments (ES6 or newer).","status":"active","version":"3.2.2","language":"javascript","source_language":"en","source_url":"https://github.com/thiagobustamante/typescript-ioc","tags":["javascript","ioc","di","cdi","typescript","node","dependency injection","dependency inversion"],"install":[{"cmd":"npm install typescript-ioc","lang":"bash","label":"npm"},{"cmd":"yarn add typescript-ioc","lang":"bash","label":"yarn"},{"cmd":"pnpm add typescript-ioc","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Used as a decorator for properties or constructor parameters to mark them for dependency injection. Requires TypeScript decorator metadata.","wrong":"const Inject = require('typescript-ioc').Inject;","symbol":"Inject","correct":"import { Inject } from 'typescript-ioc';"},{"note":"The central class for manual dependency resolution, configuration, and testing. Provides methods like `get()` and `bind()`.","wrong":"import * as IoC from 'typescript-ioc'; const Container = IoC.Container;","symbol":"Container","correct":"import { Container } from 'typescript-ioc';"},{"note":"Enum used with the `@Scope` decorator to define the lifecycle of injected instances (e.g., `Scope.Singleton`, `Scope.Request`).","wrong":"import { ScopeType } from 'typescript-ioc';","symbol":"Scope","correct":"import { Scope } from 'typescript-ioc';"}],"quickstart":{"code":"import { Inject, Container, Scope } from \"typescript-ioc\";\n\n// Ensure your tsconfig.json has:\n// \"experimentalDecorators\": true,\n// \"emitDecoratorMetadata\": true,\n// \"target\": \"es6\"\n\ninterface ILogger {\n  log(message: string): void;\n}\n\n@Scope(Scope.Singleton)\nclass ConsoleLogger implements ILogger {\n  private readonly timestamp: Date;\n  constructor() {\n    this.timestamp = new Date();\n    console.log(`ConsoleLogger instance created at ${this.timestamp.toISOString()}`);\n  }\n  log(message: string): void {\n    console.log(`[${this.timestamp.toISOString()}] ${message}`);\n  }\n}\n\nclass DatabaseService {\n  @Inject\n  private logger!: ILogger; // '!' is TypeScript's definite assignment assertion\n\n  connect(): void {\n    this.logger.log(\"Attempting to connect to database...\");\n    // Simulate database connection logic\n  }\n}\n\nclass UserService {\n  @Inject\n  private dbService!: DatabaseService;\n\n  @Inject('APP_NAME') // Injecting a constant value defined by Container.bindName\n  private appName!: string;\n\n  createUser(username: string): void {\n    this.dbService.connect();\n    console.log(`[${this.appName}] Creating user: ${username}`);\n    // Simulate user creation logic\n  }\n}\n\n// Configure the container: bind an interface to an implementation\nContainer.bind(ILogger).to(ConsoleLogger);\n// Bind a named constant value\nContainer.bindName('APP_NAME').to('MyAwesomeApp');\n\n// Option 1: Get instance from the container to ensure all dependencies are resolved\nconst userServiceFromContainer = Container.get(UserService);\nuserServiceFromContainer.createUser(\"Alice\");\n\n// Option 2: Instantiate directly, and the container will inject dependencies\nconst anotherUserService = new UserService();\nanotherUserService.createUser(\"Bob\");\n\n// Verify singleton scope for logger (should show the same creation timestamp)\nconst logger1 = Container.get(ILogger);\nconst logger1Again = Container.get(ILogger);\nconsole.log('Are logger1 and logger1Again the same instance?', logger1 === logger1Again);\n","lang":"typescript","description":"Demonstrates basic setup with `@Inject` for property and named value injection, `@Scope` for singleton management, and `Container.bind()` for interface-to-implementation mapping. Also shows manual resolution and direct instantiation."},"warnings":[{"fix":"Ensure your `tsconfig.json` includes `'target': 'es6'` or a newer ECMAScript version in `compilerOptions`.","message":"Version 3.0.0 and above of `typescript-ioc` removed support for ES5 runtimes. Projects must target ES6 or newer.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Add `'experimentalDecorators': true` and `'emitDecoratorMetadata': true` to `compilerOptions` in your `tsconfig.json`.","message":"TypeScript decorators are a required feature and need specific compiler options enabled to function correctly with `typescript-ioc`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For an interface `ILogger` and its implementation `ConsoleLogger`, add `Container.bind(ILogger).to(ConsoleLogger);` before resolving `ILogger`.","message":"When injecting an interface, `typescript-ioc` requires an explicit binding to a concrete implementation via `Container.bind(Interface).to(Implementation)`. It cannot infer the implementation from the interface type alone.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add `'emitDecoratorMetadata': true` to `compilerOptions` in your `tsconfig.json`.","cause":"`emitDecoratorMetadata` is not enabled in `tsconfig.json`, preventing TypeScript from emitting necessary type information for `typescript-ioc` to resolve dependencies.","error":"TypeError: Cannot read properties of undefined (reading 'constructor')"},{"fix":"Add `'experimentalDecorators': true` to `compilerOptions` in your `tsconfig.json`.","cause":"`experimentalDecorators` is not set to `true` in your `tsconfig.json`, which is required for all TypeScript decorators.","error":"Error: Decorators are not enabled."},{"fix":"For interfaces, ensure an explicit `Container.bind(Interface).to(Implementation);` exists. For classes, ensure they are `@Inject`-able or bound.","cause":"Attempted to `Container.get(MyInterface)` without a prior `Container.bind(MyInterface).to(MyImplementation)` or a class that is not decorated/registered correctly.","error":"Error: Class or instance not registered in container"}],"ecosystem":"npm"}