如何在修改指定属性的同时克隆TypeScript类实例?
如何简洁复制TypeScript类实例并修改指定属性
方法1:给类添加clone实例方法(推荐,类型安全)
直接在Cat类中新增一个clone方法,接收部分属性的更新参数,返回新的类实例:
class Cat { constructor( public name: string, public age: number, public color: string ) {} // 接受Partial<Cat>类型的更新参数,返回新的Cat实例 clone(updates: Partial<Cat>): Cat { return new Cat( updates.name ?? this.name, updates.age ?? this.age, updates.color ?? this.color ) } } const sophie = new Cat('Sophie', 17, 'black') // 复制并修改name属性 const tipper = sophie.clone({ name: 'Tipper' }) console.log(tipper instanceof Cat) // true
这种方式类型检查严格,复用性强,后续修改类属性时只需同步更新clone方法即可。
方法2:编写通用工具函数(不修改原类)
如果不想改动原Cat类,可以写一个通用工具函数,利用实例的构造函数和属性合并创建新实例:
class Cat { constructor( public name: string, public age: number, public color: string ) {} } const sophie = new Cat('Sophie', 17, 'black') // 通用克隆函数,适用于构造函数参数与实例属性一一对应的类 function cloneInstance<T extends object>(instance: T, updates: Partial<T>): T { const merged = { ...instance, ...updates } // 获取实例的构造函数并指定类型 const Constructor = instance.constructor as new (name: string, age: number, color: string) => T // 传入合并后的属性作为构造函数参数 return new Constructor(merged.name, merged.age, merged.color) } const tipper = cloneInstance(sophie, { name: 'Tipper' }) console.log(tipper instanceof Cat) // true
注意:该函数依赖构造函数参数与实例属性的顺序/名称完全匹配,若类的构造逻辑更复杂(比如参数和属性不完全对应),需要调整函数逻辑。
方法3:改造构造函数支持对象参数(兼顾简洁性和兼容性)
修改Cat类的构造函数,使其支持传入对象参数,这样就能像字面量对象一样简洁地复制修改:
class Cat { public name: string; public age: number; public color: string; // 构造函数重载,兼容原参数写法和对象参数写法 constructor(name: string, age: number, color: string); constructor(props: { name: string; age: number; color: string }); constructor(arg1: string | { name: string; age: number; color: string }, arg2?: number, arg3?: string) { if (typeof arg1 === 'object') { this.name = arg1.name; this.age = arg1.age; this.color = arg1.color; } else { this.name = arg1; this.age = arg2!; this.color = arg3!; } } } const sophie = new Cat('Sophie', 17, 'black') // 直接用扩展运算符合并属性,传入构造函数 const tipper = new Cat({ ...sophie, name: 'Tipper' }) console.log(tipper instanceof Cat) // true
这种方式既保留了原有使用习惯,又能实现简洁的实例复制修改。
内容的提问来源于stack exchange,提问作者Sasgorilla
相关产品推荐
相关产品推荐

