Search code examples
typescriptnestjsprisma

ERROR Class constructor t cannot be invoked without 'new' in NestJS with Prisma


Trying to create Prisma client in NestJS app. Continuously getting error:

[Nest] 14352  - 12.05.2023, 23:21:13   ERROR [ExceptionHandler] Class constructor t cannot be invoked without 'new'

TypeError: Class constructor t cannot be invoked without 'new'                                                     
    at new PrismaService (C:\work\js\cyno-desu\dist\prisma\prisma.service.js:66:42)                                
    at Injector.instantiateClass (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:351:19)
    at callback (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:56:45)
    at Injector.resolveConstructorParams (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:136:24)
    at Injector.loadInstance (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:61:13)
    at Injector.loadProvider (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:88:9)
    at Injector.lookupComponentInImports (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:281:17)
    at Injector.lookupComponentInParentModules (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:245:33)
    at Injector.resolveComponentInstance (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:200:33)
    at resolveParam (C:\work\js\cyno-desu\node_modules\@nestjs\core\injector\injector.js:120:38)

Code throwing error:

    import { Injectable, OnModuleInit, INestApplication } from '@nestjs/common';
    import { PrismaClient } from '@prisma/client';
    
    @Injectable()
    export class PrismaService extends PrismaClient implements OnModuleInit {
      async onModuleInit() {
        await this.$connect();
      }
    
      async enableShutdownHooks(app: INestApplication) {
        this.$on('beforeExit', async () => {
          await app.close();
        });
      }
    }

Dependencies:

  "devDependencies": {
    "@nestjs/cli": "^9.0.0",
    "@nestjs/schematics": "^9.0.0",
    "@nestjs/testing": "^9.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "29.5.0",
    "@types/node": "18.15.11",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "29.5.0",
    "prettier": "^2.3.2",
    "prisma": "^4.13.0",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "29.0.5",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "4.2.0",
    "typescript": "^4.7.4"
  },

I have tried to insert new keyword in different places but I feel like it's issue with dependency injection on NestJS side. It's such a simple example I'm baffled nobody would've spot the bug yet. I used to write some code in Java, so I'm quite accustomed to objectivity but here I have no idea what is the problem.


Solution

  • https://bobbyhadz.com/blog/typescript-class-constructor-cannot-be-invoked-without-new

    Class constructor cannot be invoked without 'new' in TypeScript

    The "Class constructor cannot be invoked without new" error occurs when the target property in tsconfig.json is set to lower than es6 or you instantiate a class without the new operator.

    To solve the error, set target to es6 and use the new operator when instantiating classes.

    The first thing you should do is open your tsconfig.json file and make sure target is set to es6 or more recent.

    tsconfig.json

    {
      "compilerOptions": {
        "target": "es6",
        // ... your other options
      }
    }
    

    The target option sets the language version for the emitted JavaScript files.

    All modern browsers (and Node.js) support all ES6 features. When your target option is set to something older than es6 (e.g. es5), TypeScript has to transpile your classes to functions, which could be problematic in some cases. If this is the cause of the error, setting target to es6 should resolve it.

    Make sure to restart your code editor and development server if the error persists.

    My tsconfig.build.json

    {
      "extends": "./tsconfig.json",
      "exclude": ["node_modules", "test", "dist", "**/*spec.ts"],
      "compilerOptions": {
       
        //THIS!@
        "target": "es5",
        "module": "commonjs",
        "strict": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "baseUrl": "./",
        "paths": {
          "*": ["src/*"]
        },
        "endOfLine": "crlf" // set endOfLine to "crlf" for Windows CRLF
      }
    }