typescript - Reconstruct generic class with parameters in the constructor
问题描述
I am trying to create a class method that will reconstruct the class with given data.
For example,
class A {
constructor (one, two) {...}
public static from(data: A): A {
return Object.assign(new A(), data);
}
}
And then do something like:
let someObj = A.from({one: 'hello', two: 'world'}
This works fine. But now I want to make this method generic, to call it with any class.
I have tried
export function from<T>(type: { new (): T }, input: T): T {
return Object.assign(new type(), input);
}
But the issue is that this wont work if the class needs arguments in the constructor.
How can I achieve that?
解决方案
您可以使用Object.create
指定的原型创建对象,而无需调用构造函数。通过将对象的原型设置为type.prototype
,它将是类的一个实例type
,因此它将具有该类定义的方法,就像调用new type()
.
function from<T>(type: { new(...args: any[]): T }, input: T): T {
return Object.assign(Object.create(type.prototype), input);
}
必须说这明显违反了封装,所以你必须保证你只会用它来创建具有有效内部状态的对象。由于没有调用构造函数,因此对象没有机会验证自己的状态。
例子:
class A {
constructor(public x: number) { }
getX() { return this.x; }
}
var a = new A(1);
var b = from(A, a);
var c = from(A, { x: 4 }); // type error here, unfortunately.
console.log(b.getX()); // logs 1
console.log(c.getX()); // logs 4
不幸的是,类型注释input: T
会导致编译器抱怨{ x: 4 }
没有实例应该具有的getX
属性。A
我们可以通过构造一个排除方法的映射类型来解决这个问题:
type FieldsOf<T> = Pick<T, { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]>;
function from<T>(type: { new(...args: any[]): T }, input: FieldsOf<T>): T {
return Object.assign(Object.create(type.prototype), input);
}
推荐阅读
- java - 我的 Java 程序显示错误:IOException: Stream closed - 但我没有对此 Stream 进行 close() 调用
- c++ - 创建一个数据结构,接受键值对并按值对数据进行排序
- python - 无法使用请求从网页中获取特定项目
- arrays - 为什么我的阵列在我推入它们后仍然是空的?
- python - 索引超出范围,用于减少嵌套列表的循环
- python - 如何从有条件的字典中提取值
- html - 使用 Bootstrap 4 在无限行内居中卡
- python - python删除所有重复项包括该元素
- jquery - 如何将 $scope.value 名称放入 $('input:radio[name="optradio"][value="$scope.t_color"]') .attr('checked', true);
- angular - Angular 8 - 自动刷新指令