title: Setting correct type for optional settings object argument in TypeScript
body: <p>As an example, say I'm building a frontend JavaScript library in TypeScript for creating carousels. We have the function <code>createCarousel</code> that accepts two arguments: a reference to a DOM element whose children will be slides, and an optional second argument for various settings for the library.</p>
  <pre class="lang-js prettyprint-override"><code>interface CarouselSettings = {
    dots: boolean;  // whether to show navigation dots
    arrows: boolean; // whether to show prev/next arrows
    autoplay: boolean; // does slideshow play automatically
    // etc...
  }
  
  function createCarousel(carouselRoot: HTMLElement, userSettings?: CarouselSettings): void {
    const defaultSettings: CarouselSettings = {
      dots: true,
      arrows: true,
      autoplay: false,
      // etc...
    };
  
    let finalSettings: CarouselSettings;
  
    if(typeof userSettings !== undefined) {
      finalSettings = { ...defaultSettings, ...userSettings };
    } else {
      finalSettings = defaultSettings;
    }
  
    // ... create carousel code
  }
  
  export default createCarousel;
  </code></pre>
  <p>So far so good. The problem arises for users of this function:</p>
  <pre class="lang-js prettyprint-override"><code>const galleryRoot = document.getElementById('carousel-root') as HTMLElement;
  
  // doesn't contain some of the required properties of CarouselSettings
  const settings = {
    dots: false
  };
  
  createCarousel(galleryRoot, settings); // triggers TypeScript type error
  </code></pre>
  <p>I know there will be no runtime error here because the user settings will be blended with the default settings in the function, but the TS type checker doesn't like that my <code>settings</code> doesn't match the <code>CarouselSettings</code> interface.</p>
  <p>I can think of a few fixes, none of which seem idiomatic:</p>
  <ol>
  <li>Set all properties on the <code>CarouselSettings</code> interface to optional. This doesn't reflect my API well though, because those properties are <strong>not</strong> optional within the library.</li>
  <li>Have the users of the library assert their <code>settings as CarouselSettings</code>. I don't like this solution because it makes the library harder to use and adds an extra interface for them to import.</li>
  <li>Create a second interface called <code>UserCarouselSettings</code> where all the properties are optional. Leads to code duplication and two interfaces to update when new settings are updated.</li>
  </ol>
  <p>Are there better solutions? Appreciate the help!</p>