1

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?

uloco
  • 2,283
  • 4
  • 22
  • 37
  • How would TypeScript know about a call having been made by the code? That is a runtime thing, while TypeScript provides compile time checks. – nbokmans Aug 20 '21 at 10:01
  • I know that this is a runtime thing. I was just thinking if there is a common approach or feature of TypeScript, where I could tell the compiler about such things. – uloco Aug 20 '21 at 10:03
  • 1
    It's not possible for typescript since it only works on compiletime and not on runtime.You could type selectors `non nullable` and actually use a predefined state which is not `undefined`. Like this you will be sure there's always defined data. In `Redux` you pass a default state at which point you can setup empty default data. – Silvan Bregy Aug 20 '21 at 10:04

1 Answers1

3

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

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875