如何为TypeScript接口添加自定义属性?(ngx-logger场景)
解决ngx-logger添加自定义名称配置的类型问题
方法1:类型断言跳过TypeScript检查
因为JavaScript本身允许给对象添加额外属性,只是TypeScript的类型检查会报错,所以可以用类型断言让编译器接受扩展后的配置:
public getLogger(name: string): NGXLogger { if (name in this.logCfg['loggers']) { let logger = _.cloneDeep(this.rootLogger); let level = this.getLevel(this.logCfg['loggers'][name]['level']); // 合并原有配置和name字段,再断言为ngx-logger的配置类型 const config = { ...this.rootLogger.getConfigSnapshot(), level, name } as NGXLoggerConfig; // 替换为ngx-logger实际的配置接口名 logger.updateConfig(config); return logger; } return this.rootLogger; }
这种方式最简单直接,适合快速解决问题,唯一的小缺点是TypeScript不会再校验name字段的类型,但对你的场景完全够用。
方法2:扩展ngx-logger的配置接口
如果ngx-logger的配置是用interface(而非type)定义的,可以在你的代码里扩展这个接口,TypeScript会自动合并接口定义:
// 在你的服务文件顶部添加扩展声明 declare module 'ngx-logger' { interface NGXLoggerConfig { name?: string; } } // 原代码可以直接给config添加name字段 public getLogger(name: string): NGXLogger { if (name in this.logCfg['loggers']) { let logger = _.cloneDeep(this.rootLogger); let level = this.getLevel(this.logCfg['loggers'][name]['level']); let config = this.rootLogger.getConfigSnapshot(); config.level = level; config.name = name; // 这里不会再触发类型错误 logger.updateConfig(config); return logger; } return this.rootLogger; }
这种方式更优雅,TypeScript会完全认可name字段,但如果ngx-logger的配置是用type定义的,这个方法就不生效了。
方法3:包装Logger类,手动添加名称前缀
如果上面两种方法都不适用,可以自己写一个包装类,把组件名称存起来,调用日志方法时手动添加到输出内容里:
// 自定义包装类 class NamedLogger { constructor(private logger: NGXLogger, public name: string) {} debug(message: any, ...additional: any[]) { this.logger.debug(`[${this.name}]`, message, ...additional); } info(message: any, ...additional: any[]) { this.logger.info(`[${this.name}]`, message, ...additional); } warn(message: any, ...additional: any[]) { this.logger.warn(`[${this.name}]`, message, ...additional); } error(message: any, ...additional: any[]) { this.logger.error(`[${this.name}]`, message, ...additional); } // 按需实现其他日志方法(如trace、log等) } // 修改getLogger返回包装后的实例 public getLogger(name: string): NamedLogger { if (name in this.logCfg['loggers']) { let logger = _.cloneDeep(this.rootLogger); let level = this.getLevel(this.logCfg['loggers'][name]['level']); let config = this.rootLogger.getConfigSnapshot(); config.level = level; logger.updateConfig(config); return new NamedLogger(logger, name); } return new NamedLogger(this.rootLogger, 'root'); }
这种方法完全不依赖ngx-logger的内部结构,兼容性最好,只是需要手动实现所有你用到的日志方法。
内容的提问来源于stack exchange,提问作者Oeg Bizz
相关产品推荐
相关产品推荐

