title: How to type a Tuple with type inference in Typescript
body: <p>I'm trying to write the type signature of a function that replaces the values of an object with a list of changes to the object.</p>
  
  <p>I'm having trouble finding the most accurate type for the function.</p>
  
  <p>The function in question is:</p>
  
  <pre><code>export const patchObjFn = (
      defaultVal: any
  ) =&gt; &lt;T extends object, K extends keyof T&gt; (
      changeObj: Replacement&lt;T&gt;[] | Replacement&lt;T&gt;,
      moddingObj: T
  ) =&gt; {
      const moddedObj = cloned(moddingObj);
      const isSingleElement = changeObj.length !== 0
          &amp;&amp; (changeObj.length === 1 || changeObj.length === 2)
          &amp;&amp; !Array.isArray(changeObj[0]);
      const changes = isSingleElement
          ? [changeObj] as ([K] | [K, T[K]])[]
          : changeObj  as ([K] | [K, T[K]])[];
      for (const change of changes) {
          const [propName, val] = change.length === 1
              ? [change[0], defaultVal]
              : change;
          moddedObj[propName] = val;
      }
      return moddedObj;
  };
  </code></pre>
  
  <p>And the type I've reached is:</p>
  
  <pre><code>export type Replacement&lt;T extends object, K extends keyof T&gt; = [K] | [K, T[K]];
  </code></pre>
  
  <p>But this doesn't really work, since if K is <code>'hello' | 'world'</code> and T is <code>{ hello: string; world: number; }</code>, we can pass in <code>['hello', 42]</code>.</p>
  
  <p>I would like to prevent this, but am unsure how to do so.</p>