有没有一种干净的方法来在 TypeScript 中创建静态可继承的泛型构造函数?



>我正在创建一个"可序列化"抽象类,我可以使用将json对象作为参数的方法调用来创建其子级。我让它使用以下代码,但它导致了一个相当笨拙的解决方案。

我当前的代码:

abstract class Serializable {
public static deserialize<T>(jsonString: string, ctor: { new (): T}) {
const newCtor = new ctor;
const jsonObject = JSON.parse(jsonString);
for (const propName of Object.keys(jsonObject)) {
newCtor[propName] = jsonObject[propName]
}
return newCtor;
}
public static deserializeList<T>(jsonString: string, ctor: { new (): T}) {
let newCtor = new ctor;
const newArray = new Array<typeof newCtor>();
const jsonArray = JSON.parse(jsonString)['staff'];
for (const jsonObject of jsonArray) {
newCtor = new ctor;
for (const propName of Object.keys(jsonObject)) {
newCtor[propName] = jsonObject[propName]
}
newArray.push(newCtor);
}
return newArray;
}
}
export class Employee extends Serializable {
firstName: string;
lastName: string;
}

我现在可以像这样创建一个新的 Employee 实例:

const testJson = '{"firstName": "Max", "lastName": "Mustermann"}';
const testEmployee = Employee.deserialize<Employee>(testJson, Employee);

理想情况下,我希望能够做到这一点:

const testJson = '{"firstName": "Max", "lastName": "Mustermann"}';
const testEmployee = Employee.deserialize(testJson);

我觉得应该有一种方法不必在一行中写三次"员工",但是用"typeof this"替换任何东西都让我一无所获。 我意识到这可以通过不使构造函数静态而是有两行来避免:

const testJson = '{"firstName": "Max", "lastName": "Mustermann"}';
const testEmployee = new Employee();
testEmployee.deserialize(testJson);

但是,如果有任何干净的方法可以在一行中做到这一点,我将不胜感激!我不完全理解ctor: { new (): T}论点的作用,所以我对解决方案的无知可能源于此。

是的,你可以这样做:

abstract class Serializable {
public static deserialize<T>(this: { new(): T }, jsonString: string): T {
const newCtor = new (this as any)();
...
}
}
const testEmployee = Employee.deserialize2(testJson); // type of testEmployee is Employee

请注意,有将this转换为any,这是必需的,因为Serializable是抽象的,因此编译器抱怨它无法实例化。
如果删除抽象部分,则也可以删除此强制转换。

此外,没有必要像这样迭代属性,你可以简单地使用 Object.assign:

public static deserialize<T>(this: { new (): T }, jsonString: string): T {
return Object.assign(new (this as any)(), JSON.parse(jsonString));
}

这是关于类型的。

abstract class Serializable {
public static deserialize(jsonString: Employee) {
const newCtor = new Employee();
const jsonObject = JSON.parse(jsonString);
for (const propName of Object.keys(jsonObject)) {
newCtor[propName] = jsonObject[propName]
}
return newCtor;
}
public static deserializeList(jsonString: Employee) {
let newCtor = new Employee();
const newArray: Employee[] = [];
const jsonArray = JSON.parse(jsonString)['staff'];
for (const jsonObject of jsonArray) {
newCtor = new ctor;
for (const propName of Object.keys(jsonObject)) {
newCtor[propName] = jsonObject[propName]
}
newArray.push(newCtor);
}
return newArray;
}
}

如果你不能重写抽象类,那么你就被迫按照你已经做过的方式使用它。

最新更新