Angular 5生产构建报错:受保护继承属性提示“不存在于组件类型”
解决Angular prod构建时protected属性访问报错的问题
我之前在Angular 5版本也碰到过完全一样的问题,核心原因在于开发模式(JIT编译)和生产模式(默认AOT编译)对访问修饰符的检查严格程度天差地别:
ng serve用的是JIT(即时编译),运行时才解析模板,对类的访问修饰符限制很宽松,哪怕你在模板里直接用protected/private属性也不会触发报错;ng build --prod默认启用AOT(预编译),编译阶段就会把模板转换成TypeScript代码,这时候会严格遵循TypeScript的访问权限规则——模板代码属于组件类的外部上下文,只能访问组件类的public成员,哪怕是父类的protected属性,在子类模板里直接访问也会被判定为越权。
下面给你几个不用把status改成public的解决方案,既能保持原有的封装意义,又能顺利通过prod构建:
方案1:在子类中添加public getter包装protected属性
在继承ModuleBaseComponent的子类里,写一个public的getter方法来代理父类的status属性,这样模板里访问的是子类的public成员,内部逻辑还是依赖父类的protected属性:
export class YourChildComponent extends ModuleBaseComponent { // 包装父类的protected status,对外暴露只读权限 get compStatus() { return this.status; } }
之后在子类模板里用{{compStatus}}代替原来的{{status}}即可。
方案2:将基类属性改为protected readonly(可选)
如果status属性不需要在子类外部被修改,只是需要在模板里读取,可以把基类里的声明改成protected readonly status = 'inac...',再配合方案1的getter,既能保证属性不会被外部篡改,又能满足AOT的访问要求。
方案3:排查模板的误用场景
确认一下是不是在不属于基类或子类内部逻辑的模板里误用了status——比如有没有在其他无关组件的模板里引用了这个属性?如果是基类自己的模板使用自身的protected属性,AOT是允许的;但如果是跨组件的非法引用,就要及时修正。
其实Angular从版本5开始收紧AOT的检查规则是件好事,能帮我们提前发现代码里的封装漏洞,避免运行时的潜在风险。
内容的提问来源于stack exchange,提问作者nsk
相关产品推荐
相关产品推荐

