我有一个超类,它是许多子类(Customer, Product, ProductCategory…)的父类(Entity)。
我想在Typescript中动态克隆一个包含不同子对象的对象。
例如:拥有不同产品的客户拥有一个ProductCategory
var cust:Customer = new Customer ();
cust.name = "someName";
cust.products.push(new Product(someId1));
cust.products.push(new Product(someId2));
为了克隆对象的整个树,我在实体中创建了一个函数
public clone():any {
var cloneObj = new this.constructor();
for (var attribut in this) {
if(typeof this[attribut] === "object"){
cloneObj[attribut] = this.clone();
} else {
cloneObj[attribut] = this[attribut];
}
}
return cloneObj;
}
当new被转译为javascript时,将引发以下错误:错误TS2351:不能对缺少调用或构造签名的表达式使用'new'。
虽然脚本工作,但我想摆脱转译错误
对于深度克隆对象,可以包含另一个对象,数组等,我使用:
const clone = <T>(source: T): T => {
if (source === null) return source
if (source instanceof Date) return new Date(source.getTime()) as any
if (source instanceof Array) return source.map((item: any) => clone<any>(item)) as any
if (typeof source === 'object' && source !== {}) {
const clonnedObj = { ...(source as { [key: string]: any }) } as { [key: string]: any }
Object.keys(clonnedObj).forEach(prop => {
clonnedObj[prop] = clone<any>(clonnedObj[prop])
})
return clonnedObj as T
}
return source
}
Use:
const obj = {a: [1,2], b: 's', c: () => { return 'h'; }, d: null, e: {a:['x'] }}
const objClone = clone(obj)
对于深度克隆对象,可以包含另一个对象,数组等,我使用:
const clone = <T>(source: T): T => {
if (source === null) return source
if (source instanceof Date) return new Date(source.getTime()) as any
if (source instanceof Array) return source.map((item: any) => clone<any>(item)) as any
if (typeof source === 'object' && source !== {}) {
const clonnedObj = { ...(source as { [key: string]: any }) } as { [key: string]: any }
Object.keys(clonnedObj).forEach(prop => {
clonnedObj[prop] = clone<any>(clonnedObj[prop])
})
return clonnedObj as T
}
return source
}
Use:
const obj = {a: [1,2], b: 's', c: () => { return 'h'; }, d: null, e: {a:['x'] }}
const objClone = clone(obj)
下面是deepCopy在TypeScript中的实现(代码中不包含任何内容):
const deepCopy = <T, U = T extends Array<infer V> ? V : never>(source: T ): T => {
if (Array.isArray(source)) {
return source.map(item => (deepCopy(item))) as T & U[]
}
if (source instanceof Date) {
return new Date(source.getTime()) as T & Date
}
if (source && typeof source === 'object') {
return (Object.getOwnPropertyNames(source) as (keyof T)[]).reduce<T>((o, prop) => {
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop)!)
o[prop] = deepCopy(source[prop])
return o
}, Object.create(Object.getPrototypeOf(source)))
}
return source
}