使用class-transformer将JSON转为Customer类实例失败问题排查
问题:class-transformer的plainToInstance无法正确转换为Customer类实例
问题详情
导入语句
import { plainToInstance } from 'class-transformer';
Customer JSON
{ "id": "1", "name": "John", "surname": "Doe", "email": "j.doe.test@gmail.com", "phone": "123456789" }
Customer类定义
import { Field, ObjectType, Directive, ID } from '@nestjs/graphql'; import { Address } from './address'; @ObjectType() @Directive('@key(fields: "id")') export class Customer { @Field(() => ID) id: string; @Field() name: String; @Field({nullable: true}) surname?: String; @Field() email: String; @Field({nullable: true}) phone?: String; @Field() customerType: String; @Field() customerStatus: String; @Field(() => [Address], { nullable: true }) addresses?: [Address] }
转换代码
let customer : Customer = plainToInstance(Customer, json) as Customer; console.log('customer.email');
控制台结果
Customer email: undefined
打印整个customer变量能看到包含email的JSON对象,但直接new Customer并赋值id后实例显示正常。
解决方案
你遇到的问题主要来自三个错误,逐一修正即可:
1. 传入plainToInstance的参数错误
plainToInstance要求第二个参数是已解析的JavaScript对象,但你直接传入了JSON字符串。需要先通过JSON.parse解析:
const customerObj = JSON.parse(json);
2. 类属性类型使用错误
你用了大写的String(引用类型),TypeScript中应该用小写的string(基本类型),class-transformer对基本类型的处理更可靠。同时数组类型不要用元组[Address],改为标准数组Address[]。
3. 缺少class-transformer的属性暴露装饰器
NestJS的@Field是用于GraphQL Schema生成的,class-transformer默认不会自动识别这些属性,需要添加@Expose装饰器标记需要转换的属性。
修正后的完整代码
修正后的Customer类
import { Field, ObjectType, Directive, ID } from '@nestjs/graphql'; import { Address } from './address'; import { Expose } from 'class-transformer'; @ObjectType() @Directive('@key(fields: "id")') export class Customer { @Expose() @Field(() => ID) id: string; @Expose() @Field() name: string; @Expose() @Field({nullable: true}) surname?: string; @Expose() @Field() email: string; @Expose() @Field({nullable: true}) phone?: string; @Expose() @Field() customerType: string; @Expose() @Field() customerStatus: string; @Expose() @Field(() => [Address], { nullable: true }) addresses?: Address[]; }
修正后的转换代码
import { plainToInstance } from 'class-transformer'; const json = `{ "id": "1", "name": "John", "surname": "Doe", "email": "j.doe.test@gmail.com", "phone": "123456789" }`; // 先解析JSON字符串为JS对象 const customerObj = JSON.parse(json); // 转换为Customer实例,无需额外类型断言 const customer: Customer = plainToInstance(Customer, customerObj); // 正确打印email属性 console.log('Customer email:', customer.email);
内容的提问来源于stack exchange,提问作者g_m
相关产品推荐
相关产品推荐

