title: Type return value when recursively re-mapping keys in object
body: <p>I have a mapper which takes in any object, and if there is a key named 'fields' in it, it's replaced by its contents. So for example,</p>
  <pre><code>const obj = { x: 'hey', fields: { y: 'you' } }
  const mapped = contentfulMapper(obj);
  
  // mapped = { x: 'hey', y: 'you' }
  
  </code></pre>
  <p>Or</p>
  <pre><code>const givenObj = {
    a: &quot;sdf&quot;,
    w: { 
      a2: 343,
      a3: true,
      fields: {
        a4: &quot;ll&quot;,
        q: {
          fields: {
            a5: [2, 4, &quot;lk&quot;]
          }, 
        },
      },
    }, 
  };
  const mapped = contentfulMapper(givenObj);
  
  /* mapped = {
    a: &quot;sdf&quot;,
    w: { 
      a2: 343,
      a3: true,
      a4: &quot;ll&quot;,
      q: {
        a5: [2, 4, &quot;lk&quot;]
      }, 
    }, 
  }; */
  </code></pre>
  <p>Returning a <code>Record&lt;string, unknown&gt;</code> isn't great though, so my question is how can I type this correctly?</p>
  <pre><code>type TContentfulModel = {
    fields?: undefined | Record&lt;string, TContentfulModel&gt;;
  };
  
  
  const contentfulMapper = (
    obj: Record&lt;string, TContentfulModel | unknown&gt;
  ) =&gt; {
    let out: Record&lt;string, unknown&gt; = {};
  
    Object.keys(obj).forEach((key) =&gt; {
      const field = obj[key] as TContentfulModel;
      if (key === 'fields') {
        const mappedField = contentfulMapper(field);
        out = { ...out, ...mappedField };
        
      } else {
        out[key] =
          typeof obj[key] === 'object' &amp;&amp; !Array.isArray(obj[key])
            ? contentfulMapper(field)
            : obj[key];
      }
    });
  
    return out;
  };
  </code></pre>