NestJS Validation Pipe中如何将字符串数组转为真实数组?
解决NestJS中Query参数数组解析为字符串的问题
问题场景
调用接口 http://you.host/api/v1/all?lookup=["s1","s2"] 后,控制器收到的结果是:
{ lookup: '["s1", "s2"]' }
但期望得到的是:
{ lookup: ["s1", "s2"] }
当前使用的Filter类和控制器代码如下:
Filter类定义:
export class Filter { @Type(() => String) @IsArray() @IsString({ each: true }) lookup?: string[]; }
控制器代码:
@UsePipes(new ValidationPipe({ transform: true })) @Get('all') async getAll(@Query() data: Filter): Promise<string[]> { console.log(data) return data }
尝试过用JSON.parse(data)处理,但没有效果。
解决方案
方案1:自定义字段转换逻辑
问题出在Query参数默认是字符串类型,即使格式像JSON数组,NestJS也不会自动解析。我们可以用class-transformer的@Transform装饰器手动处理:
修改Filter类,替换掉原来的@Type(() => String),添加自定义转换:
import { Transform } from 'class-transformer'; import { IsArray, IsString } from 'class-validator'; export class Filter { @Transform(({ value }) => { try { const parsed = JSON.parse(value); // 校验解析结果是否为字符串数组 if (Array.isArray(parsed) && parsed.every(item => typeof item === 'string')) { return parsed; } return value; // 不符合格式时返回原值,让验证器后续报错 } catch (e) { return value; // JSON解析失败时返回原值 } }) @IsArray() @IsString({ each: true }) lookup?: string[]; }
这样处理后,控制器就能正确把传入的JSON字符串解析为字符串数组,输出结果会符合预期。
方案2:改用多值参数传参(可选)
如果允许调整请求格式,也可以把参数改成多值形式:
http://you.host/api/v1/all?lookup=s1&lookup=s2
这种情况下,NestJS的ValidationPipe会自动把lookup解析为字符串数组,不需要修改Filter类的装饰器,直接保留原来的@IsArray和@IsString({ each: true })即可。
内容的提问来源于stack exchange,提问作者PIN
相关产品推荐
相关产品推荐

