Angular继承MatSnackBar报错:私有属性_overlay存在重复声明
解决Angular中继承MatSnackBar时的私有属性冲突问题
嘿,这个问题我之前做Angular项目的时候也踩过坑!
你遇到的错误核心原因是TypeScript对私有属性的严格限制——MatSnackBar里的_overlay是用private修饰的私有属性,这种属性只能在它自己的类内部访问,子类根本没法继承或者访问它。当你尝试让SnackbarService继承MatSnackBar时,TypeScript的类型检查器会认为两个类的私有属性声明不兼容,所以抛出了Types have separate declarations of a private property '_overlay'这个错误。
其实Angular官方并不推荐直接继承Material的组件/服务类,更好的做法是通过依赖注入来封装MatSnackBar,这样既能复用它的功能,又能轻松扩展自己的逻辑。给你个示例代码:
import { Injectable } from '@angular/core'; import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar'; @Injectable({ providedIn: 'root' }) export class SnackbarService { // 注入MatSnackBar而非继承它 constructor(private matSnackBar: MatSnackBar) {} // 封装基础的open方法,可添加默认配置或自定义逻辑 open(message: string, action?: string, config?: MatSnackBarConfig) { // 设置默认配置,可根据需求调整 const defaultConfig: MatSnackBarConfig = { duration: 3000, horizontalPosition: 'end', verticalPosition: 'bottom' }; // 合并用户传入的配置与默认配置 const mergedConfig = { ...defaultConfig, ...config }; return this.matSnackBar.open(message, action, mergedConfig); } // 自定义成功提示方法 openSuccess(message: string) { this.open(message, '关闭', { panelClass: 'snackbar-success' }); } // 自定义错误提示方法 openError(message: string) { this.open(message, '关闭', { panelClass: 'snackbar-error' }); } }
在这个示例里,我们没有继承MatSnackBar,而是把它注入到SnackbarService中,然后封装它的open方法,还添加了自定义的openSuccess和openError方法来快速展示不同类型的提示。这种方式完全避开了私有属性的冲突问题,也更符合Angular依赖注入的设计理念。
如果你的需求特别复杂,一定要修改MatSnackBar的底层行为,可以去看看它的源码,看看有没有protected修饰的成员可以利用,或者通过自定义Overlay服务来间接调整,但绝大多数场景下,封装的方式就足够好用了。
内容的提问来源于stack exchange,提问作者Mike Me
相关产品推荐
相关产品推荐

