You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用class-transformer转换对象后调用方法报TypeError问题求助

class-transformer嵌套对象转换后实例方法调用报错:TypeError: undefined is not a function

问题场景

使用class-transformer的plainToInstance将JSON反序列化为BasicTime实例后,调用嵌套属性hour的getAs24Hour()或toString()方法时抛出TypeError: undefined is not a function。但直接转换Hour对象时方法调用正常。

相关代码如下:

类定义

export class Hour {
    hour: number
    isAm: boolean

    constructor(hour: number, isAm: boolean) {
        if (hour < 0 || hour > 11) {
            throw new Error("Hour should be between 0 and 11 inclusive.")
        }

        this.hour = hour
        this.isAm = isAm
    }

    getAs24Hour(): number {
        return this.isAm ? this.hour : this.hour + 12
    }

    toString(): string {
        return this.hour < 10 ? `0${this.hour.toString()}` : this.hour.toString()
    }
}


export class BasicTime {
    @Type(() => Hour)
    hour: Hour;

    @Type(() => Minute)
    min: Minute;

    constructor(hour: Hour, min: Minute) {
        this.hour = hour
        this.min = min
    }
}

转换代码

let plain = JSON.parse(jsonString)
let time = plainToInstance(BasicTime, plain as BasicTime)
time.hour.getAs24Hour() // 报错:函数未定义

问题原因

这是class-transformer的已知问题:当嵌套类拥有带参数的构造函数时,库无法自动正确实例化嵌套对象,导致转换后的hour只是普通JSON对象(POJO),而非Hour类的实例,因此不存在类原型上的方法。

解决方案

方案1:使用@Transform手动实例化嵌套对象

在嵌套属性上添加@Transform装饰器,手动调用类的构造函数完成实例化:

import { Transform, Type } from 'class-transformer';

export class BasicTime {
    @Type(() => Hour)
    @Transform(({ value }) => new Hour(value.hour, value.isAm))
    hour: Hour;

    @Type(() => Minute)
    @Transform(({ value }) => new Minute(value.min)) // 适配Minute类的构造逻辑
    min: Minute;

    constructor(hour: Hour, min: Minute) {
        this.hour = hour;
        this.min = min;
    }
}

方案2:给嵌套类添加无参构造函数

修改Hour类,添加无参构造函数供class-transformer自动实例化,同时保留原有带参构造的逻辑:

export class Hour {
    hour: number;
    isAm: boolean;

    constructor(hour?: number, isAm?: boolean) {
        if (hour !== undefined && isAm !== undefined) {
            if (hour < 0 || hour > 11) {
                throw new Error("Hour should be between 0 and 11 inclusive.");
            }
            this.hour = hour;
            this.isAm = isAm;
        }
    }

    getAs24Hour(): number {
        return this.isAm ? this.hour : this.hour + 12;
    }

    toString(): string {
        return this.hour < 10 ? `0${this.hour.toString()}` : this.hour.toString();
    }
}

方案3:配置plainToInstance选项(部分版本有效)

在调用plainToInstance时传入enableImplicitConversion选项,允许库自动处理构造函数参数:

let time = plainToInstance(BasicTime, plain as BasicTime, {
    enableImplicitConversion: true
});

注意:该选项的有效性取决于class-transformer的版本,部分旧版本可能不支持此方式处理带参构造的嵌套类。

内容的提问来源于stack exchange,提问作者broun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 03:35:29