深克隆可读实例



,假设我们有一个带有引用另一个类的属性的类。我希望能够深入克隆它的"不变"(或Readonly)的实例:

import * as _ from 'lodash'; 
interface IParent{
   name: string;
}
interface IChild{
   name: string;
   parent: IParent;
}
public class Child implements IChild{
   public name: string;
   public parent: string;
   constructor(props: IChild){
      Object.assign(this, props);
   }
   toImmutable(): Readonly<IChild> {
       return _.cloneDeep(this); //lodash deep clone
   }
}

当此代码在child实例Readonly上提供第一类属性时,仍可以编辑引用的对象:

let child = new Child({ 
   name: 'abc',
   parent: { name: 123 }
});
let immutable = child.toImmutable();
immutable.name = 'abc';  //not allowed
immutable.parent.name = 'abc';  //this is allowed!!!

是否有一个优雅的解决方案可以让我在克隆的对象上读取所有内容?

注意:看起来lodash具有一种称为cloneDeepWith的方法,该方法采用"定制器" ...想知道这是否可能朝着正确的方向发展。

关键是创建一个自定义类型DeepReadonly<T>,而不是Readonly<>

type DeepReadonly<T> = {
    readonly [K in keyof T]: DeepReadonly<T[K]>;
}

这种类型将递归地将读取属性应用于所有嵌套对象。

在操场上参见这一点

type DeepReadonly<T> = {
    readonly [K in keyof T]: DeepReadonly<T[K]>;
}
import * as _ from 'lodash'; 
interface IParent{
   name: string;
}
interface IChild{
   name: string;
   parent: IParent;
}
class Child implements IChild{
   public name: string;
   public parent: IParent;
   constructor(props: IChild){
      Object.assign(this, props);
   }
   toImmutable(): DeepReadonly<IChild> {
       return _.cloneDeep(this); //lodash deep clone
   }
}
let child = new Child({ 
   name: 'abc',
   parent: { name: "123" }
});
let immutable = child.toImmutable();
immutable.name = 'abc';  //not allowed
immutable.parent.name = 'abc';  //not allowed

最新更新