Search code examples
typescriptundefinedoptional-chaining

Typescript does not understand undefined return type when used with optional chaining


I have a very simple code:

const foo = (state: RootState): MyData => undefined;

This gives an error:

Type 'undefined' is not assignable to type 'MyData'.

Which is quite reasonable since my type MyData does not allow undefined.

But if I now write this:

const foo = (state: RootState): MyData => state.data?.myData;

Then it compiles without troubles. I don't understand what is going on here since if state.data is undefined then it should be really returning undefined and should be quite obvious to the compiler.

Am I missing something here?

P.S. This is the minimal example for types:

type State = {
  data: {
    myData: MyData;
  };
}

type MyData = {

}

Solution

  • It sounds like data is not optional in RootState.

    TypeScript complains about both of these functions, since — as you say — MyData | undefined is not assignable to MyData:

    interface RootState {
        data?: {
            myData: MyData;
        }
    }
    
    interface MyData {
        bar: string;
    }
    
    const foo1 = (state: RootState): MyData => undefined;
    
    const foo2 = (state: RootState): MyData => state.data?.myData;
    

    Playground link

    But it's happy if data in RootState is not optional:

    interface RootState {
        data: {
            myData: MyData;
        }
    }
    

    Playground link

    It's happy because the TypeScript compiler knows that the ? there is non-functional, because data isn't optional, can't have the value undefined, and can't have the value null. So state.data.myData and state.data?.myData do exactly the same thing: yield a value of type MyData.