我有以下控制器来创建新用户。请求正文 (
CreateUser
) 有一个可选字段 locationName
。我有一个管道,如果请求正文中未定义,则将 locationName
更改为 null
。
当我使用
@Body
装饰器时,我可以正确地获取主体,并且 locationName
在运行时永远不会是 undefined
。
对于 Swagger,我可以看到
locationName
是可选的。但是当我尝试在代码中访问 createUserInput.locationName
时,Typescript 仍然抱怨该值可以是 undefined
(我理解)。
如何为控制器代码引入不同类型和为 Swagger 引入另一种类型?
User
控制器:@Post("/users")
async createUser(
@Body(CreateUserLocationPipe) createUserInput: CreateUser
): Promise<User> {
return await this.usersService.create(createUserInput);
}
CreateUser
班级:export class CreateUser {
@ApiProperty({ description: "The email of the user" })
email: string;
@ApiProperty({ description: "Location of the user" })
locationName: string | undefined | null;
}
CreateUserLocationPipe
管道:@Injectable()
export class CreateUserLocationPipe {
transform(value: string | null | undefined): string | null {
if (value.locationName === undefined) {
value.locationName = null;
}
}
}
我们可以为控制器的输入创建一个不同的类。
export class CreateUserControllerInput extends OmitType(CreateUser, ["locationName"] as const) {
locationName: WellKnownLocationName | null;
locationPlantId: string | null;
}
然后我们可以区分控制器主体和 swagger 的请求主体,如下所示。
@Post("/users")
@ApiBody({ type: CreateUser }) // This is exposed by swagger as the request body
async createUser(
@Body(CreateUserLocationPipe) createUserInput: CreateUserControllerInput // This is the type for the controller
): Promise<User> {
return await this.usersService.create(createUserInput);
}