title: How to map a relay (graphql) connection to an edge's nodes using generics with Typescript
body: <p>I have recently been experimenting with React, GraphQL, Apollo, and Relay conforming queries.</p>
  <p>Right now I have a GraphQL backend that has a simple GraphQL schema with some Connection queries for returning lists of entities that can be paginated using Relay server specifications.</p>
  <p>On the front end, I've found myself repeating myself after making said queries
  with code that usually looks something like the below:</p>
  <pre><code>type isDefined = &lt;T&gt;(value: T | null | undefined): value is T =&gt; value !== null &amp;&amp; value !== undefined;
  
  export const AppleListComponent: React.FC = () =&gt; {
    const { data } = useAppleQuery(); // FWIW, generating this with graphql-code-generator
    const apples = data &amp;&amp; data.apples;
    const appleNodes = apples &amp;&amp; apples.edges.map(apple =&gt; (
      apple ? apple.node : undefined
    )).filter(apple =&gt; isDefined(apple));
  
    return (
      &lt;div&gt;
        {appleNodes &amp;&amp; appleNodes.map(apple =&gt; (
          &lt;p key={apple.text}&gt;{apple.text}&lt;/p&gt;
        ))}
      &lt;/div&gt;
    );
  };
  </code></pre>
  <p>The song and dance of checking for presence are necessary due to the Relay spec mandating that edges and nodes be Nullable.</p>
  <p>I find myself often repeating this transformation from a relay format to a simple array of nodes format.
  I decided to see if I could make a helper function that takes something that conforms to a connection interface and returns either undefined or a list of mapped nodes.</p>
  <p>That attempt looked like this:</p>
  <pre><code>type Maybe&lt;T&gt; = T | null;
  type isDefined = &lt;T&gt;(value: T | null | undefined): value is T =&gt; value !== null &amp;&amp; value !== undefined;
  
  type Connection&lt;T&gt; = Maybe&lt;{ edges: Array&lt;Maybe&lt;{ node: Maybe&lt;T&gt; }&gt;&gt;}&gt;;
  
  export const connectionToNodes = &lt;T&gt;(connection: Connection&lt;T&gt;): Maybe&lt;T[]&gt; =&gt; (
    connection &amp;&amp; connection.edges.map(edge =&gt; (
      edge ? edge.node : undefined
    )).filter(isDefined)
  );
  </code></pre>
  <p>Which allows the previous component to become</p>
  <pre><code>export const AppleListComponent: React.FC = () =&gt; {
    const { data } = useAppleQuery();
    const apples = data &amp;&amp; data.apples;
    const appleNodes = connectionToNodes(apples);
  
    return (
      &lt;div&gt;
        {appleNodes &amp;&amp; appleNodes.map(apple =&gt; (
          &lt;p key={apple.text}&gt;{apple.text}&lt;/p&gt;
        ))}
      &lt;/div&gt;
    );
  };
  </code></pre>
  <p>My problem here is that my type for Connection of course does not exactly match
  up with my type I'm passing in which has more properties that look like:</p>
  <pre><code>Maybe&lt;(
    { __typename?: 'AppleConnection' }
    &amp; { edges: Array&lt;Maybe&lt;(
      { __typename?: 'AppleEdge' }
      &amp; { node: Maybe&lt;{ __typename?: 'AppleType' }
        &amp; { __typename?: 'QuestionType' }
          &amp; Pick&lt;QuestionType, 'text'&gt;
      &gt; }
    )&gt;&gt; }
  )&gt;
  </code></pre>
  <p>So I end up getting errors about the question being of any type, and errors that
  what I am passing to <code>connectionToNodes</code> does not match the specified type.</p>
  <p>My instinct is that I need to say my type <code>T</code> is a subtype of something else - of
  course for application purposes I don't care whether it's an <code>Apple</code> or <code>Pear</code>
  connection/edge/node, but I'd like for it to be ultimately inferred - any advice
  on how to achieve this?</p>