首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >深度克隆只读实例

深度克隆只读实例
EN

Stack Overflow用户
提问于 2017-09-16 19:19:22
回答 1查看 2.2K关注 0票数 2

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

代码语言:javascript
复制
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上生成第一个类属性时,仍然可以编辑引用的对象:

代码语言:javascript
复制
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的方法,它需要一个“自定义器”.想知道这是否会朝着正确的方向发展。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-17 09:25:29

关键是创建一个自定义类型的DeepReadonly<T>,您将使用它而不是Readonly<>

代码语言:javascript
复制
type DeepReadonly<T> = {
    readonly [K in keyof T]: DeepReadonly<T[K]>;
}

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

在操场上看这个

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46257609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档