title: Typescript : match function input type to output type in Array.reduce function
body: <p>I run into a problem when trying to generate an object through Array.reduce function. This code will work without any issues in javascript. However in typescript I'm not able to match types from the reduce function and it throws the Error shown below.</p>
  <p>This is a small example, in my case there are many more input types and 2-3 levels of processing like the <strong>buildSchema</strong> function below. I would prefer to generate them through the reduce function rather than manually listing them as seen in the <strong>morph</strong> object below.</p>
  <p>Any idea how I can resolve this through the type system ? To infer the types based on input. So I can still have the type-safety but not have to copy paste the same code over and over just for different input keys ?</p>
  <p><strong>Sample Code:</strong></p>
  <pre><code>
  type inputs = &quot;alpha&quot; | &quot;beta&quot; | &quot;gamma&quot;;
  
  type AlphaSchema = {
      pet: string,
      house: string
  }
  
  type BetaSchema = {
      boss: string,
      work: string,
  }
  
  type GammaSchema = {
      monk: string,
      temple: string,
  }
  
  // Anything I can try using this type ? Using generics and keyof ?
  // &lt;T extends keyof Schemas&gt; =&gt; Schemas[T] ?
  type Schemas = {
      'alpha': AlphaSchema,
      'beta': BetaSchema,
      'gamma': GammaSchema 
  }
  
  type manualMorph = typeof morph
  
  //////////////////////
  
  const morphTypes : [&quot;alpha&quot;, &quot;beta&quot;, &quot;gamma&quot;] = [&quot;alpha&quot;, &quot;beta&quot;, &quot;gamma&quot;];
  
  const buildSchema = {
      'alpha' : (str1: string, str2: string): AlphaSchema =&gt; { return {pet: str1, house: str2} },
      'beta' : (str1: string, str2: string): BetaSchema =&gt; { return {boss: str1, work: str2} },
      'gamma' : (str1: string, str2: string): GammaSchema =&gt; { return {monk: str1, temple: str2} }
  }
  
  // Manually generated morph object
  const morph = {
      'alpha' : buildSchema['alpha'],
      'beta' : buildSchema['beta'],
      'gamma' : buildSchema['gamma'],
  }
  
  // Morph from reduce
  const morphFromReduce: manualMorph = morphTypes.reduce((acc, type) =&gt; {
  
      acc[type] = buildSchema[type];
      return acc;
  }, &lt;manualMorph&gt;{})
  </code></pre>
  <p><strong>Error:</strong></p>
  <p>Type <strong>'((str1: string, str2: string) =&gt; AlphaSchema) | ((str1: string, str2: string) =&gt; BetaSchema) | ((str1: string, str2: string) =&gt; GammaSchema)'</strong>
  is not assignable to type
  <strong>'((str1: string, str2: string) =&gt; AlphaSchema) &amp; ((str1: string, str2: string) =&gt; BetaSchema) &amp; ((str1: string, str2: string) =&gt; GammaSchema)'</strong>.</p>
  <p>Type <strong>'(str1: string, str2: string) =&gt; AlphaSchema'</strong>
  is not assignable to type
  <strong>'((str1: string, str2: string) =&gt; AlphaSchema) &amp; ((str1: string, str2: string) =&gt; BetaSchema) &amp; ((str1: string, str2: string) =&gt; GammaSchema)'</strong>.</p>
  <p>Type <strong>'(str1: string, str2: string) =&gt; AlphaSchema'</strong>
  is not assignable to type
  <strong>'(str1: string, str2: string) =&gt; BetaSchema'</strong>.</p>
  <p>Type <strong>'AlphaSchema'</strong> is missing the following properties from type <strong>'BetaSchema': boss</strong></p>
  <p>I'm using typescript 4.1.3</p>