Is dependency injection in NestJS dependent on the features of TypeScript, for instance?

When implementing the dependency injection pattern in NestJS, such as shown in this example from the official documentation:

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  // Other methods...
}

How does this mechanism function? It seems that TypeScript is transpiled into plain JavaScript, potentially losing the type information for the CatsService class. How does NestJS manage to correctly inject the appropriate class in this scenario?

Answer №1

When it comes to dependency injection, Typescript doesn't necessarily play a crucial role. In fact, even in NestJS, you can achieve dependency injection using plain JavaScript with the help of Babel as a transpiler. I have delved into this topic further here, explaining how decorators work with typescript, and Semyon Volkov has demonstrated how these decorators are transpiled. Therefore, while TypeScript is not a strict requirement for dependency injection, Nest's preferred approach does rely on it.

In your scenario, Nest examines the type specified in `design:paramtypes` and identifies the corresponding class such as `CatsService`, allowing it to properly match and inject a `CatsService` instance where needed. Behind the scenes, there are additional mechanisms in place to manage module access, but this provides an overview of how dependency injection works.

Answer №2

When we launch a Nest app, a Dependency Injection (DI) container is automatically generated for us, regardless of whether we are using TypeScript or not. DI operates as an object that manages the relationships between different classes.

Nest will analyze all classes, excluding controllers, that we have created and register them with the DI container. Each class is mapped to its required dependencies within the container:

   class1 ---> dependencies
   class2 ---> dependencies
   class3 ---> may not have any dependencies

When it comes time to create a controller, we instruct the DI container to generate it along with the necessary dependencies. The container examines the constructor arguments to determine the required dependencies and recursively creates any services or dependencies needed.

The DI container instantiates the necessary dependencies and stores them internally so that they can be reused by other classes in the future. This ensures that the Controller can be created and returned using the pre-existing dependencies.

This process eliminates the need for manual creation of services, as the DI container handles this task for us. Dependency injection simplifies code reuse and facilitates easier testing of the application.

Answer №3

Check out this illustration. Here it is:

@Injectable()
export default class RequestService {
  constructor(
    @InjectRepository(RequestEntity)
    private requestEntityRepository: Repository<RequestEntity>,
  ) {}

After transpilation, it becomes:

let RequestService = class RequestService {
    constructor(requestEntityRepository) {
        this.requestEntityRepository = requestEntityRepository;
    }
...

RequestService = __decorate([
    common_1.Injectable(),
    __param(0, typeorm_1.InjectRepository(RequestEntity_1.default)),
    __metadata("design:paramtypes", [typeorm_2.Repository])
], RequestService);
exports.default = RequestService;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error in Redux with TypeScript: "Argument of type 'AsyncThunkAction<any, number, {}>' is not compatible with parameter of type 'AnyAction'"

So I've been working on this dispatch function: const dispatch = useAppDispatch() const handleFetch = (e: React.MouseEvent<HTMLAnchorElement>) => { const target = e.target as Element dispatch(fetchCity(parseInt(ta ...

Error Alert: missing property data in angular 5 type

I attempted to design an interface in interface.ts. The data consists of an array of objects inside the Column. Below is the code for my interface: export class User { result: boolean; messages: string; Column=[]; data=[]; } export class Column { name ...

What is the method to utilize attributes from one schema/class in a separate schema?

Consider the scenario presented below: Base.ts import Realm from 'realm'; export type BaseId = Realm.BSON.ObjectId; export interface BaseEntity { id?: BaseId; createdAt: string; updatedAt: string; syncDetails: SyncDetails; } e ...

Troubleshooting: Issues with Angular 2 Dependency Injection

I am facing an issue with my angular2 application that involves a simple dependency injection, but it seems to be not working correctly. Can anyone help me figure out what might be missing? Below is the error message I am encountering: EXCEPTION: Cannot ...

Error message on Cypress with TypeScript: No test specification files detected

Encountering the error "Unable to run because no spec files were found, even though there is a .ts spec file in Cypress. Execute the command below in the terminal: npx cypress run --spec="./cypress/integration/specs/Test1.spec.ts". Attempted to run the t ...

ESLint detected a promise being returned in a function argument where a void return type was expected

I'm encountering a recurring error whenever I run my ESLint script on multiple routers in my server. The specific error message is as follows: error Promise returned in function argument where a void return was expected @typescript-eslint/no-misuse ...

Tips for upgrading outdated TypeScript code to the newest version

Previous iterations of TypeScript exhibit several differences, like using 'bool' instead of 'boolean'. I attempted to make the php-typescript compiler function in Visual Studio 2015, but encountered more than 2000 errors primarily due ...

Error message: "Uncaught TypeError in NextJS caused by issues with UseStates and Array

For quite some time now, I've been facing an issue while attempting to map an array in my NextJS project. The particular error that keeps popping up is: ⨯ src\app\delivery\cart\page.tsx (30:9) @ map ⨯ TypeError: Cannot read pr ...

Enhancing Code: Eliminate Duplicates from an Array

I have a code that removes duplicates from an array, but I believe it could be improved for better elegance. Any suggestions? Interface Definition export interface SomeClass { version: number, typeDescription: string } Test Data someClasses: SomeCla ...

What is the best way to ensure that each service call to my controller is completed before proceeding to the next one within a loop in Angular?

Calling an Angular service can be done like this: this.webService.add(id) .subscribe(result => { // perform required actions }, error => { // handle errors }); // Service Definition add(id: number): Observable < any > { retu ...

Is there a way to programmatically close Chrome that is running in Kiosk mode?

Currently, I am facing an issue with my Angular 9 app running in Chrome within a Kiosk mode environment. I urgently require a solution to close the Chrome browser as there is no keyboard attached to the PC handling the app. Is there a way to achieve this ...

The module 'AppModule' has encountered an unexpected declaration of 'AnyComponent'

Hi there, I'm currently working with Angular2 and am facing an issue when trying to use two classes in the same Typescript file. During compile time, no errors are shown. However, when attempting to run the page, the console.log displays the followin ...

What is the best way to tally up the letters within a table?

Currently, I am working on a task to count letters and display them in a table. The existing table is functional but has too many rows and incorrect counts. A 2 ...

Finding keys corresponding to specific values in an object using Typescript

I have a straightforward scenario in mind. I am looking to create a function called pluckOnlyStringValues that takes an object obj and a key. The main requirement is that the key passed should correspond to a string value in the object, ensuring that pluck ...

Error message: 'import not located' when using custom types in Vue 3 with Vite/Vitesse

I'm currently working on a Vue 3 project using Vitesse (which is based on Vite). I created a custom type called ProductData in my src/types.ts file. However, when I try to use this type in one of my pages, the page fails to load and I see multiple con ...

Enabling the "allowUnreachableCode" Compiler Option in Visual Studio 2015 Triggers "JsErrorScriptException (0x3001)" Issue

We've implemented TypeScript in our Visual Studio 2015 (Update 2) setup for a non-ASP.Net project consisting of pure HTML and JavaScript. In order to disable the 'allowUnreachableCode' option, we made adjustments in the tsconfig file. It&apo ...

error TS2339: The attribute 'properties' is not accessible on the class 'TestPage'

Utilizing a typescript abstract class as the base class of my layout component in React has been essential for my project. The implementation of this base class looks something like this: import { IPageLayoutActions, IPageLayoutLocalState, IPageLayoutProp ...

Harnessing the power of React context alongside React hooks in TypeScript

Here is an example demonstrating my attempt at implementing react's context with react hooks. The goal is to easily access context from any child component using the code snippet below: const {authState, authActions} = useContext(AuthCtx); First, I ...

Troubleshooting Clarifai object error while invoking "model.predict" within Angular Framework

I've been attempting to utilize Clarifai's color API to extract the different colors present in an image. Unfortunately, I am encountering challenges when trying to call the API, as it consistently returns empty objects. Below is the snippet of ...

The TypeScript error TS2339 states that the property "firestore" does not exist in the Cartservice type in Angular

I have integrated angularefire into the angular.io 'take a look tutorial' (shopping cart) in order to utilize firebase firestore for products data and orders processing. I have managed to partially replace products.ts and shipping.json, as well a ...