NestJS使用OmitType创建DTO时触发TypeError问题求助
NestJS中OmitType创建的DTO映射时报错TypeError: Class constructor cannot be invoked without 'new'
问题描述
在NestJS项目的POST接口中,所有通过OmitType创建的DTO类,在框架映射时都会抛出TypeError: Class constructor OmitTypeClass cannot be invoked without 'new'错误。此前该接口及其他接口均正常运行,怀疑是版本兼容问题。
错误信息
TypeError: Class constructor OmitTypeClass cannot be invoked without 'new' improvein-challenge-nestjs-1 | at new CreateActorDto (/usr/local/apps/myapp/build/src/features/actor/actors.model.js:65:42) improvein-challenge-nestjs-1 | at TransformOperationExecutor.transform (/usr/local/apps/myapp/node_modules/src/TransformOperationExecutor.ts:160:22) improvein-challenge-nestjs-1 | at ClassTransformer.plainToInstance (/usr/local/apps/myapp/node_modules/src/ClassTransformer.ts:77:21) improvein-challenge-nestjs-1 | at Object.plainToClass (/usr/local/apps/myapp/node_modules/src/index.ts:71:27) improvein-challenge-nestjs-1 | at ValidationPipe.transform (/usr/local/apps/myapp/node_modules/@nestjs/common/pipes/validation.pipe.js:60:39) improvein-challenge-nestjs-1 | at /usr/local/apps/myapp/node_modules/@nestjs/core/pipes/pipes-consumer.js:16:33 improvein-challenge-nestjs-1 | at processTicksAndRejections (node:internal/process/task_queues:95:5)
相关代码
Actors控制器代码
import { Body, Controller, Headers, HttpStatus, Logger, Post, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiBody, ApiConflictResponse, ApiCreatedResponse, ApiExtraModels, ApiTags, ApiUnauthorizedResponse, getSchemaPath, } from '@nestjs/swagger'; import { ActorsService } from './actors.service'; import { CreateActorDto, CreateActorResponse } from './actors.model'; import { Actor } from './actor.entity'; import BaseResponse from '../../models/base.response.model'; import BaseExceptionResponse from '../../models/base.exception.response.model'; import { ApiTagsEnum } from '../../enums/api.tags.enum'; @Controller('actors') export class ActorsController { constructor(private readonly actorsService: ActorsService) {} @ApiExtraModels(BaseResponse, CreateActorResponse) @ApiCreatedResponse({ schema: { allOf: [ { $ref: getSchemaPath(BaseResponse) }, { properties: { content: { type: 'array', items: { $ref: getSchemaPath(CreateActorResponse) }, }, }, }, ], }, description: 'Actors', }) @ApiUnauthorizedResponse({ type: BaseExceptionResponse, description: 'Unauthorized', }) @ApiConflictResponse({ type: BaseExceptionResponse, description: 'Duplicate actor name', }) @ApiBearerAuth('access-token') @ApiTags(ApiTagsEnum.ACTORS) @ApiBody({ type: CreateActorDto }) //@UseGuards(AuthGuard) @Post() async createActor( @Headers() headers, @Body() payload: CreateActorDto, ): Promise<BaseResponse<CreateActorResponse>> { const response: Actor = await this.actorsService.createActor(payload); Logger.log(response); return new BaseResponse( HttpStatus.CREATED, 'Actor', new CreateActorResponse(response), ); } }
Actors模型代码
import { ApiProperty, OmitType } from '@nestjs/swagger'; import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; import { Actor } from './actor.entity'; export class BaseActor { @ApiProperty() id: number; @ApiProperty({ type: 'string', required: false, example: new Date().toLocaleDateString(), }) @IsNotEmpty() @IsString() birthDate: string; @IsNotEmpty() @IsString() @ApiProperty({ type: 'string', minLength: 1, required: true }) name: string; @IsOptional() @IsString() @ApiProperty({ type: 'string', minLength: 1, required: false }) nationality?: string; } export class CreateActorDto extends OmitType(BaseActor, ['id']) {} export class CreateActorResponse extends BaseActor { constructor(actor: Actor) { super(); Object.assign(this, actor); } }
Dev依赖配置
"devDependencies": { "@nestjs/cli": "^10.0.3", "@nestjs/schematics": "^10.0.1", "@nestjs/testing": "^10.0.2", "@types/express": "^4.17.13", "@types/jest": "29.5.1", "@types/node": "^16.11.10", "@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", "source-map-support": "^0.5.20", "supertest": "^6.1.3", "ts-jest": "29.1.0", "ts-loader": "^9.2.3", "ts-node": "10.7.0", "tsconfig-paths": "4.2.0", "typescript": "4.5.2" },
问题原因与解决方案
这个错误核心是TypeScript版本与NestJS 10.x及相关依赖不兼容:你当前使用的TypeScript 4.5.2版本过低,而NestJS 10.x要求TypeScript版本至少为4.8.x。低版本TS编译后的类继承代码,无法正确处理OmitType生成的动态类实例化逻辑。
具体修复步骤:
升级TypeScript版本
安装兼容NestJS 10.x的TS版本(推荐4.9.x或5.x):npm install typescript@^4.9.5 --save-dev同步核心依赖版本
确保class-transformer和class-validator与NestJS版本匹配:npm install class-transformer@^0.5.1 class-validator@^0.14.0调整TS配置
修改tsconfig.json,确保以下配置正确:{ "compilerOptions": { "target": "ES2021", "experimentalDecorators": true, "emitDecoratorMetadata": true, "module": "commonjs", "strict": true } }清理缓存并重建
删除旧依赖、锁文件和构建产物,重新安装并构建:rm -rf node_modules package-lock.json dist npm install npm run build
额外注意
如果是从NestJS旧版本升级到10.x,需同步升级@nestjs/common、@nestjs/core等核心包到10.x版本,避免跨版本兼容问题。
内容的提问来源于stack exchange,提问作者Purplex
相关产品推荐
相关产品推荐

