Search code examples
typescriptreduxnullablenon-nullable

Define type that is no longer undefined after data fetched Typescript


Is there a way to tell TypeScript, that a certain type is no longer nullable if a certain call has been made in the code before?

So for example I have a call to an API and afterwards I know that the data is defined. But this call is happening somewhere at the outer shell of the application code, so when used later on, the data is already fetched.

More concretely I am fetching data with redux thunk and afterwards the data is stored in redux. But my selectors are all saying that the return type could be possibly undefined. Of course I could just type my Selectors to return the non nullable type but then I would need to be careful of where I am using the selectors.

Is there any elegant way or feature of TypesScript that could solve this problem better than defining multiple types of selectors? What are your approaches to this common problem?


Solution

  • If you're using the data in a place where you know it will be non-null, you can use an assertion type guard (the best link I can find for it at the moment is in the 3.7 release notes). You define it like this:

    function assertNotNull<T>(data: T | null): asserts data is T {
        if (data === null) {
            throw new Error(`null was found unexpectedly`);
        }
    }
    

    Then where you're using the data:

    assertNonNull(theData);
    // ...here, `theData`'s type has been narrowed by TypeScript to no longer include `null`...
    

    In addition to assuring TypeScript that the data variable is not null, this both documents and checks your belief that it cannot be null where you're using it.

    Example on the playground