如何避免JavaScript类按引用传递问题,同时保留TypeScript泛型类型
报错原因
你定义的泛型EffectInstance extends Effect允许传入Effect的任意子类型,你手动判断仅覆盖了Effect和PlayerEffect两种类型,TS无法确认这两种类型能匹配所有可能的EffectInstance子类型,因此抛出类型不兼容错误。
解决方案
方案1:为基类新增clone方法(最推荐)
在Effect基类定义克隆方法,所有子类自行重写实现自己的克隆逻辑,既保证类型完全匹配,也不用在构造函数里判断类型:
class Effect { name: string; constructor(name: string) { this.name = name; } clone(): this { return new Effect(this.name) as this; } } class PlayerEffect extends Effect { ignoreRaces: string[]; constructor(name: string, ignoreRaces: string[]) { super(name); this.ignoreRaces = ignoreRaces; } clone(): this { return new PlayerEffect(this.name, [...this.ignoreRaces]) as this; } }
构造函数直接调用克隆方法即可:
constructor(effect: EffectInstance, names: string[], count?: number) { this.effect = effect; const altEffect = effect.clone(); for (const name of names) { this.custom.set(name, altEffect); } }
方案2:添加类型断言(适合无法修改基类的场景)
如果你确认已经覆盖了所有EffectInstance的子类型,可以直接添加类型断言绕过TS校验:
constructor(effect: EffectInstance, names: string[], count?: number) { this.effect = effect; let altEffect: EffectInstance; if (effect instanceof PlayerEffect) { altEffect = new PlayerEffect(effect.name, effect.ignoreRaces) as EffectInstance; } else { altEffect = new Effect(effect.name) as EffectInstance; } for (const name of names) { this.custom.set(name, altEffect); } }
注意不要用JSON.parse(JSON.stringify())这类通用深拷贝方法,会丢失类的原型方法,导致实例类型异常。
内容的提问来源于stack exchange,提问作者Wubzy
相关产品推荐
相关产品推荐

