TypeScript:如何实现对象到类型的通用映射函数?
解决TypeScript通用映射函数中
new T()的报错问题 你遇到的这个错误是TypeScript泛型的典型坑——泛型类型T只是编译时的类型标记,在运行时会被完全擦除,所以你没办法直接把它当作可实例化的构造函数来使用new T()。下面给你两种实用的解决方案,分别对应类和接口两种常见场景:
方案一:针对类类型的映射(传入构造函数)
如果你的CommentDTO是一个类(而非接口),可以修改map函数,让它接收类的构造函数作为参数,这样运行时就能拿到实例化的入口:
public map<T>(ctor: new () => T, values: any): T { // 用传入的构造函数创建目标类型实例 const instance = new ctor(); // 遍历实例的属性,从数据源中匹配赋值 return Object.keys(instance).reduce((acc, key) => { acc[key as keyof T] = values[key]; return acc; }, instance); }
使用时需要把类本身传进去:
// 假设CommentDTO是一个定义好的类 this.responseMapper.map(CommentDTO, data);
方案二:针对接口类型的映射(手动指定属性)
如果CommentDTO是一个接口(TypeScript接口在运行时不存在实体),我们没办法通过构造函数获取属性列表,这时候可以改为手动传入需要映射的属性键,保证映射的安全性:
public map<T>(values: any, requiredKeys: (keyof T)[]): T { return requiredKeys.reduce((acc, key) => { // 可选:检查数据源中是否存在该属性,避免赋值undefined if (values && Object.prototype.hasOwnProperty.call(values, key)) { acc[key] = values[key]; } return acc; }, {} as T); }
使用时指定要映射的属性集合:
this.responseMapper.map<CommentDTO>(data, ['id', 'content', 'author']);
额外优化提示
- 如果需要处理嵌套对象的映射,可以在
reduce逻辑里递归调用map函数; - 可以添加类型守卫逻辑,检查数据源的属性类型是否符合目标类型
T的要求,避免类型不匹配的隐患; - 如果业务中类和接口场景都存在,可以通过函数重载把两个方案合并成一个灵活的通用函数。
内容的提问来源于stack exchange,提问作者sandrooco
相关产品推荐
相关产品推荐

