title: How to handle defaulted optional fields in an options parameter for a TypeScript class whilst letting user chose provided arguments?
body: <p>I'm trying to determine how to handle optional fields in an options argument for a TypeScript class whilst only requiring the user of the class to provide only the arguments they need so all other options are defaulted (use case is allowing the user to customize the class via the options)</p>
  <p>For example, if there's a class (e.g., <code>Logger</code>) that accepts an options argument (e.g., <code>IOptions</code>) where all options are optional &amp; will be defaulted in the constructor. Then all <code>IOptions</code> fields can be nullable so the user only provides the arguments they need (e.g., customizing the <code>Logger</code>). This is fine since all nullable values will be defaulted in the constructor, however, if the options argument is used throughout the class, the compiler will error since the fields are marked as nullable in <code>IOptions</code>. However, the constructor has defaulted all options so they should be safe but to avoid the error, either repeated null assertions are used (e.g., <code>this.options.logTag!!</code>) or the defaulting is repeated (e.g., <code>this.options.logTag ?? 'NONE</code>), both of these attempts to avoid errors are not ideal</p>
  <p>Please explain how a defaulted options object can be used whilst only requiring the user to provide the fields they need?</p>
  <p>Please also share any resources that might be helpful in answering this questin.</p>
  <p>Example <code>Logger</code> class:</p>
  <pre class="lang-js prettyprint-override"><code>interface IOptions {
      logTag?: string;
      // ...
  }
  
  class Logger {
      private options: IOptions; // Assume options are always contained &amp; accessed from this object.
  
      constructor(options: IOptions = {}) {
          this.options = {
              ...options,
              logTag: options.logTag ?? 'NONE',
              // ...
          }
      }
  
      private saveTag(tag: string, message: string) { // Example demonstrating requiring non-null option value (logTag could be used directly, but passed here for example).
          // ... (e.g., formatting, saving, etc.)
      }
  
      log(message: string) {
          this.saveTag(this.options.logTag); // ERROR: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  
          // ...
      }
  
  }
  
  const logger = new Logger();
  logger.log('message');
  </code></pre>