在Typescript中深度克隆实体实例吗?

时间:2018-09-23 20:20:44

标签: javascript arrays typescript

尝试:

/**
 * Deep clones an array of instances of type T and returns a new array.
 * @param array The array to deep clone
 * @return A new deep clone of the array argument
 *
 * @example
<pre>
  const original = [new Todo(), new Todo()];
  const result = [new Todo(), new Todo()];
  expect(deepClone(original)).to.eql(result);
</pre>
*/
export function deepClone<T extends Object>(array: T[]): T[] {
  return array.map((e:T) => ({...e}));
}

打字稿说:

  

[ts]传播类型只能从对象类型创建。

T extends Object是否应该照顾这个问题?

3 个答案:

答案 0 :(得分:1)

如果使用传播运算符复制对象,则新对象将不是类的实例,而是没有类型的文字对象,因此不会是现有对象的真实克隆。

>

如果要克隆的对象是您(不是外部库)定义的,则可以执行以下操作:

export function deepClone(array: any[]): any[] {
  return array.map((e:any) => (new e.constructor(e)));
}

然后在要复制的类中:

constructor(obj: any) {
   Object.assign(this, obj);
}

答案 1 :(得分:1)

我使用这种方法

https://stackblitz.com/edit/typescript-qmzgf7

const clone = obj =>
  Array.isArray(obj)
    ? obj.map(item => clone(item))
    : obj instanceof Date
      ? new Date(obj.getTime())
      : (typeof obj === 'object') && obj
        ? Object.getOwnPropertyNames(obj).reduce((o, prop) => ({ ...o, [prop]: clone(obj[prop]) }), {})
        : obj;

它不适用于您可能遇到的所有JavaScript对象,但是它可能适用于来自服务器调用的JSON格式的任何内容。

答案 2 :(得分:1)

关于您的实际实现,您应该考虑使用旧版JSON来帮助您解决此问题。

var array:Array<number> = [1,2,3];
var deepClone = clone(array);
deepClone[0] = 99;
console.log({ array, deepClone });  // returns [1,2,3] & [99,2,3]

function clone<T>(array:T[]) {
return JSON.parse(JSON.stringify(array)) as Array<T>;
}

相关问题