如何在不修改原类的前提下,阻止TypeScript公共函数调用私有方法?
解决方案
方案1:继承子类覆盖私有方法(无侵入,仅影响新创建的实例)
TypeScript的private修饰符仅作用于编译阶段的类型校验,运行时该方法依然是实例可访问的普通属性,直接覆盖为空实现即可跳过原逻辑:
export class CustomResourceFactory extends ResourceFactory { // 可直接自定义AlgoliaAppId的初始值 override AlgoliaAppId = "你的自定义前缀"; constructor() { super(); // @ts-ignore 忽略编译阶段私有方法访问报错 this.resetParams = () => { // 空实现,原resetParams的逻辑不会执行 }; } }
之后你所有需要用的地方直接实例化CustomResourceFactory即可,initTemplate的其余原有逻辑会完全复用,且不会执行resetParams。
方案2:原型猴子补丁(全局生效,无需修改原有实例化代码)
如果你不想改动原有代码中实例化ResourceFactory的逻辑,可直接修改类的原型方法实现全局生效:
// 先保存原initTemplate方法 // @ts-ignore const originalInit = ResourceFactory.prototype.initTemplate; // @ts-ignore ResourceFactory.prototype.initTemplate = function (objectName, directiveArgs) { // 临时替换resetParams为空函数,执行完原方法后再恢复,避免影响其他逻辑 // @ts-ignore const originalReset = this.resetParams; // @ts-ignore this.resetParams = () => {}; // 可在此处自定义修改AlgoliaAppId的取值 this.AlgoliaAppId = "你的自定义前缀"; // 调用原initTemplate逻辑,复用剩余的长代码 const result = originalInit.call(this, objectName, directiveArgs); // 恢复原resetParams方法 // @ts-ignore this.resetParams = originalReset; return result; };
注意事项
如果原类的resetParams是使用ES原生私有属性(写法为#resetParams,带#前缀)实现的,则无法通过上述方式覆盖。但你给出的代码中使用的是TypeScript的private关键字修饰,以上方案均可正常运行。
内容的提问来源于stack exchange,提问作者Yam Mesicka
相关产品推荐
相关产品推荐

