TypeScript泛型函数无法实例化T报错,如何实现模型数组转换?
解决TypeScript泛型无法创建实例的问题
这个坑我踩过!你遇到的问题本质是TypeScript泛型在运行时会被类型擦除——编译成JavaScript后,T只是个空占位符,JS根本不知道它对应的是Student还是其他类,自然没法用new T()创建实例。下面给你具体的修复方案:
核心思路:传入类的构造函数
要让函数知道怎么创建实例,你得把目标类的构造函数作为参数传进去。因为构造函数本身包含了创建对应实例的全部信息,TypeScript也能通过它做类型校验。
修改后的代码实现
首先重构你的泛型函数,让它接收一个构造函数参数:
// 泛型函数新增ctor参数,约束它是能接收后端数据并返回T实例的构造函数 export function mapDataToModelArrayFunction<T, U>(array: U[], ctor: new (data: U) => T): T[] { const listToReturn: T[] = []; if (Array.isArray(array)) { array.forEach(item => { // 用传入的构造函数创建实例,而不是直接new T listToReturn.push(new ctor(item)); }); } return listToReturn; }
然后在School类里调用时,把Student类(也就是它的构造函数)传进去:
export class School implements MyInterface { public students: Student[] = []; public constructor(data_from_backend: { students: unknown[] }) { // 第二个参数传入Student构造函数,TypeScript会自动推导泛型类型 this.students = mapDataToModelArrayFunction(data_from_backend.students, Student); } } export class Student implements MyInterface { public name: string; public constructor(data: { name: string }) { this.name = data.name; } }
进阶优化:添加后端数据类型约束
如果想让类型检查更严格,可以给后端数据定义接口,这样能避免传错数据结构:
// 定义后端返回的学生数据结构 interface StudentBackendData { name: string; } // 定义后端返回的学校数据结构 interface SchoolBackendData { students: StudentBackendData[]; } export class Student implements MyInterface { public name: string; // 构造函数接收明确的后端数据类型 public constructor(data: StudentBackendData) { this.name = data.name; } } export class School implements MyInterface { public students: Student[] = []; public constructor(data_from_backend: SchoolBackendData) { // 此时泛型会自动推导为Student和StudentBackendData,无需手动指定 this.students = mapDataToModelArrayFunction(data_from_backend.students, Student); } }
为什么原来的写法不行?
TypeScript的泛型是编译时特性,编译完成后所有泛型参数都会被替换成any或者unknown,运行时根本不存在T这个类型。所以直接new T()相当于尝试实例化一个不存在的类,必然报错。
内容的提问来源于stack exchange,提问作者yadbo
相关产品推荐
相关产品推荐

