title: Typescript adding "| null" to return type of Promise.all
body: <p>I have an async TS function that makes a request and casts the response data to a <code>boolean</code> and returns it, but in the calling function VS Code is telling me the return value is <code>boolean | null</code> when I make the call in <code>Promise.all</code>. Here's the code:</p>
  
  <p>The function:</p>
  
  <pre><code>import apiAxios from "../apiAxios";
  
  export default async function doesAssignmentHaveTakes(
    assignmentId: number
  ): Promise&lt;boolean&gt; {
    const response = await apiAxios.get(`/assignments/${assignmentId}/has-takes`);
  
    return !!response.data;
  }
  </code></pre>
  
  <p>And the caller:</p>
  
  <pre><code>import React, { FC, useState, useCallback } from "react";
  import styled from "styled-components/macro";
  import AssignmentForm, {
    Props as AssignmentFormProps,
    Value as AssignmentFormValue
  } from "./AssignmentForm";
  import useAsyncEffect from "../utils/useAsyncEffect";
  import getAssignmentById from "../api/assignments/getAssignmentById";
  import doesAssignmentHaveTakes from "../api/assignmentTakes/doesAssignmentHaveTakes";
  
  interface Props extends AssignmentFormProps {
    assignmentId: number;
    onSubmit(value: Value): any;
  }
  
  export interface Value extends AssignmentFormValue {
    assignmentId: number;
  }
  
  const EditAssignmentForm: FC&lt;Props&gt; = props =&gt; {
    const { assignmentId, onSubmit, ...rest } = props;
    const [showEditWarning, setShowEditWarning] = useState(false);
    const [initialValue, setInitialValue] = useState&lt;AssignmentFormValue | null&gt;(
      null
    );
  
    useAsyncEffect(
      async isCancelled =&gt; {
        const [fetchedAssignment, hasTakes] = await Promise.all([
          getAssignmentById(assignmentId),
          doesAssignmentHaveTakes(assignmentId)
        ]);
  
        if (!fetchedAssignment) {
          // TODO: Alert parent component?
          return;
        }
  
        const value: Value = {
          assignmentId: fetchedAssignment.id,
          assignment: {
            title: fetchedAssignment.title,
            subTitle: fetchedAssignment.subTitle
          },
          sets: fetchedAssignment.sets
            .map(set =&gt; ({
              id: set.id,
              index: set.index,
              questions: set.questions
                .map(question =&gt; ({
                  id: question.id,
                  index: question.index,
                  isPractice: question.isPractice,
                  questionText: question.questionText,
                  inputType: question.inputType,
                  questionImage: question.questionImage,
                  sampleResponseText: question.sampleResponseText,
                  sampleResponseImage: question.sampleResponseImage
                }))
                .sort((a, b) =&gt; a.index - b.index),
              learningTarget: set.learningTarget,
              isExampleCorrect: set.isExampleCorrect,
              exampleImage: set.exampleImage,
              character: set.character
            }))
            .sort((a, b) =&gt; a.index - b.index)
        };
  
        if (!isCancelled()) {
          setInitialValue(value);
          setShowEditWarning(hasTakes);
        }
      },
      [assignmentId]
    );
  
    const handleSubmit = useCallback(
      (value: AssignmentFormValue) =&gt; {
        onSubmit({
          ...value,
          assignmentId
        });
      },
      [onSubmit, assignmentId]
    );
  
    if (!initialValue) {
      // Loading...
      return null;
    }
  
    return (
      &lt;AssignmentForm
        {...rest}
        initialValue={initialValue}
        onSubmit={handleSubmit}
      /&gt;
    );
  };
  
  export default styled(EditAssignmentForm)``;
  </code></pre>
  
  <p>The specific lines with the issue:</p>
  
  <pre><code>  const [fetchedAssignment, hasTakes] = await Promise.all([
      getAssignmentById(assignmentId),
      doesAssignmentHaveTakes(assignmentId)
    ]);
  </code></pre>
  
  <p>And</p>
  
  <pre><code>setShowEditWarning(hasTakes);
  </code></pre>
  
  <p>The TS error:</p>
  
  <pre><code>TypeScript error in /Users/james/projects/math-by-example/client/src/components/EditAssignmentForm.tsx(71,28):
  Argument of type 'boolean | null' is not assignable to parameter of type 'SetStateAction&lt;boolean&gt;'.
    Type 'null' is not assignable to type 'SetStateAction&lt;boolean&gt;'.  TS2345
  
      69 |       if (!isCancelled()) {
      70 |         setInitialValue(value);
    &gt; 71 |         setShowEditWarning(hasTakes);
         |                            ^
      72 |       }
      73 |     },
      74 |     [assignmentId]
  </code></pre>
  
  <p>And some screenshots of the error in VS Code</p>
  
  <p><a href="https://i.stack.imgur.com/vq1LG.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/vq1LG.png" alt="VS Code type tooltip"></a></p>
  
  <p><a href="https://i.stack.imgur.com/N8dxJ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/N8dxJ.png" alt="VS Code error tooltip"></a></p>
  
  <p>Why does TS add <code>null</code> to the resolved types of <code>Promise.all</code>?</p>