TypeScript中如何通过反射加载不同类型的JSON对象数组?
TypeScript 反射实现JSON到对应类型实例的转换
核心思路
无需使用switch判断,通过类型名称-构造函数映射表实现动态实例化,扩展性极强,新增子类仅需更新映射表即可。
步骤实现
- 创建类型映射表
先建立字符串类型名与对应类构造函数的映射,确保所有映射的类都是Base的子类:
class Base { public id: number; public typeName: string; } class Extend1 extends Base { public foo: string; } class Extend2 extends Base { public someProperty: boolean; } // 类型名到构造函数的映射表 const typeMap: Record<string, new () => Base> = { Extend1: Extend1, Extend2: Extend2 };
- 实现通用转换方法
遍历JSON数组,根据每个元素的typeName从映射表获取构造函数,创建实例后用Object.assign将JSON属性赋值给实例:
function loadFromJson(jsonArray: Array<{id: number; typeName: string} & Record<string, unknown>>): Base[] { return jsonArray.map(item => { const Constructor = typeMap[item.typeName]; if (!Constructor) { throw new Error(`未知类型: ${item.typeName}`); } // 创建对应类型的实例 const instance = new Constructor(); // 将JSON属性赋值到实例 Object.assign(instance, item); return instance; }); }
- 测试验证
注意:原JSON中第一个元素的name字段需改为foo(匹配Extend1的属性定义),否则属性无法正确赋值:
const json = [ {id: 1, typeName: "Extend1", foo: "toto"}, {id: 2, typeName: "Extend2", someProperty: true} ]; const myArray: Base[] = loadFromJson(json); console.log(myArray[0] instanceof Extend1); // true console.log(myArray[1] instanceof Extend2); // true
扩展说明
- 如果子类需要带参数的构造函数,可以调整映射表和实例化逻辑,比如在构造实例时传入必要参数,或者在
Base类中添加初始化方法统一处理属性赋值。 - 映射表可单独抽离成配置文件,方便批量管理类型映射。
内容的提问来源于stack exchange,提问作者Alexandre TRINDADE
相关产品推荐
相关产品推荐

