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

如何用JSON导入属性修改类实例并保留原类类型?

TypeScript 自定义类对象序列化/反序列化问题解决

我是编程新手,若该问题已有解答还请见谅——我没能找到合适的解决方案!

我定义了一个creature类,其中部分属性是其他自定义类的实例:

export class creature {
    pos: vector2;
    target: vector2;
    path: Array<vector2>;
    length: number;
    maxDist: number;
    weights: number;
    id: string;
    mainArrayId: number;
    segments: Array<creatureJoint>;
    head: creatureHead;
    legs: Array<creatureJoint>;
    interactingId: string;
    state: string;
    traits: { [key: string] : number };
    health: number;
    energy: number;
}

我的保存/加载流程是:先对对象执行JSON.stringify()保存,加载时用JSON.parse()解析,再创建creature新实例,最后用解析后的JSON属性填充实例。加载函数如下:

export function replaceCurrentState(loadedState : { [key : string]: creature }) : void {
    creatures = [];
    deadCreatures = [];
    creaturesReference = {};

    Object.keys(loadedState).forEach(function(i) {
        new creature(new vector2(0,0),16,4,2,i);
        let baseCreature : creature = creaturesReference[i];
        let loadCreature : creature = loadedState[i];
        for (let [key, value] of Object.keys(baseCreature)) {
        }
    });
}

现在遇到两个问题:

  • JSON无法识别自定义类,解析后vector2这类属性会变成普通对象,而非原类实例。
  • 尝试遍历属性赋值时,出现“cannot assign to type never”错误。

解决思路

JSON只能序列化基本类型和普通对象,无法保存类的原型信息,必须手动处理自定义类的实例还原,同时修正遍历赋值的类型问题。

1. 给自定义类添加实例还原方法

以vector2为例,添加静态方法用于从JSON对象创建类实例,可选添加自定义序列化逻辑确保保存的数据简洁:

export class vector2 {
    x: number;
    y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    // 静态方法:从JSON对象还原vector2实例
    static fromJSON(obj: {x: number, y: number}): vector2 {
        return new vector2(obj.x, obj.y);
    }

    // 可选:自定义序列化逻辑,只保存必要属性
    toJSON() {
        return {x: this.x, y: this.y};
    }
}

同理给creatureJoint、creatureHead添加相同逻辑的fromJSON方法。

2. 修改加载函数,针对性处理属性赋值

放弃盲目遍历,手动区分基本类型和自定义类型属性,确保类型匹配:

export function replaceCurrentState(loadedState : { [key : string]: any }) : void {
    creatures = [];
    deadCreatures = [];
    creaturesReference = {};

    Object.values(loadedState).forEach(loadData => {
        // 创建新的creature实例
        const newCreature = new creature(
            vector2.fromJSON(loadData.pos),
            loadData.length,
            loadData.maxDist,
            loadData.weights,
            loadData.id
        );
        
        // 赋值基本类型属性
        newCreature.mainArrayId = loadData.mainArrayId;
        newCreature.interactingId = loadData.interactingId;
        newCreature.state = loadData.state;
        newCreature.traits = {...loadData.traits};
        newCreature.health = loadData.health;
        newCreature.energy = loadData.energy;

        // 还原自定义类实例/数组
        newCreature.target = vector2.fromJSON(loadData.target);
        newCreature.path = loadData.path.map(vec => vector2.fromJSON(vec));
        newCreature.segments = loadData.segments.map(joint => creatureJoint.fromJSON(joint));
        newCreature.head = creatureHead.fromJSON(loadData.head);
        newCreature.legs = loadData.legs.map(joint => creatureJoint.fromJSON(joint));

        // 将实例加入全局集合
        creatures.push(newCreature);
        creaturesReference[newCreature.id] = newCreature;
    });
}

3. 若坚持遍历赋值,修正类型错误

如果想通过遍历实现,需要添加类型断言并判断属性类型,避免类型不匹配:

Object.entries(baseCreature).forEach(([key, _]) => {
    // 断言key为creature的合法属性名
    const propKey = key as keyof creature;
    const loadValue = loadCreature[propKey];
    
    // 根据属性类型进行实例还原
    if (propKey === 'pos' || propKey === 'target') {
        baseCreature[propKey] = vector2.fromJSON(loadValue);
    } else if (propKey === 'path') {
        baseCreature[propKey] = loadValue.map(vec => vector2.fromJSON(vec));
    } else if (propKey === 'segments' || propKey === 'legs') {
        baseCreature[propKey] = loadValue.map(joint => creatureJoint.fromJSON(joint));
    } else if (propKey === 'head') {
        baseCreature[propKey] = creatureHead.fromJSON(loadValue);
    } else {
        // 基本类型直接赋值
        baseCreature[propKey] = loadValue;
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:25:23