TypeScript Class Composition Leading to advanced patterns with Private Properties
I'm deploying to production and I've searched everywhere and can't find a clear answer... I'm working with TypeScript 4.5 and trying to implement class composition, but I'm running into unexpected behavior related to private properties. I have a base class `BaseLogger` that has a private property `_logLevel` and a method `log`. I'm extending this class with `FileLogger` and `ConsoleLogger`, but it seems like the private property is not accessible as I expected, leading to some confusion in my logs. Here's the relevant code: ```typescript class BaseLogger { private _logLevel: string; constructor(logLevel: string) { this._logLevel = logLevel; } log(message: string) { console.log(`[${this._logLevel}] ${message}`); } } class FileLogger extends BaseLogger { log(message: string) { super.log(`File: ${message}`); } } class ConsoleLogger extends BaseLogger { log(message: string) { super.log(`Console: ${message}`); } } const fileLogger = new FileLogger('DEBUG'); fileLogger.log('This is a debug message.'); const consoleLogger = new ConsoleLogger('INFO'); consoleLogger.log('This is an info message.'); ``` When I run the above code, it seems to work correctly, outputting: ``` [DEBUG] File: This is a debug message. [INFO] Console: This is an info message. ``` However, if I try to access `_logLevel` directly in `FileLogger` or `ConsoleLogger`, TypeScript throws an behavior: ``` Property '_logLevel' is private and only accessible within class 'BaseLogger'. ``` I understand that private properties are not accessible in derived classes, but I feel like there's a need to access some class-level properties while composing these classes. What are best practices here? Should I consider using protected properties instead, or is there a better design pattern for logging that allows more flexibility without exposing sensitive internals? Any insights would be greatly appreciated! Has anyone else encountered this? What's the best practice here?