Search code examples
typescriptcompiler-warningsunreachable-code

Suppressing the "not all paths return a value" Typescript warning when a code path is unreachable


I have a function foobar(x:string) which will not return if x is the empty string. Otherwise, it return another string.

So I can't declare it to return "never", and if I declare it to return "string", TS doesn't realise the code afterwards may not be reached

(Yes, this is a horrid design. No, I can't change it)

Sometimes, I need to use it with an empty x in another function which in other branches returns a value. So something like

function f(n:number) 
{

    if (n==0) {
        foobar("")
    }
    else
    {
        return n - 1
    }

}

TS complains because not all paths return a value. So I would like to tell the compiler that foobar does not return (or, equivalently the code after it is unreachable). Making something up, something like:

function f(n:number) 
{

    if (n==0) {
        foobar("")
        /** @notreachable */
    }
    else
    {
        return n - 1
    }

}

Can I do this? What else can I do? I could return something of type never, maybe, but how do I get a never "value" to return?


Solution

  • Have you tried function overloads:

    function foobar(val: string): string;
    function foobar(val: ''): never;
    function foobar(val: string): string {
      if (val === '') {
        // while (true) {
        //   console.log('Infinite loop also works fine');
        // }
        throw new Error('never returns');
      } else {
        return 'new value';
      }
    }
    
    
    function f(n: number) {
      if (n === 0) {
        foobar('');
      } else {
        return n - 1;
      }
    }
    

    Update I think similar approach will work for empty objects as well:

    interface NoProps {
      [a: string]: never;
    }
    
    interface X {
      a?: string;
    }
    
    function foobar(val: NoProps): never;
    function foobar(val: X): string;
    function foobar(val: NoProps | X): string {
      if (val.a === undefined) {
        throw new Error('never returns');
      } else {
        return 'new value';
      }
    }
    
    
    function f(n: number) {
      if (n === 0) {
        foobar({});
      } else {
        return n - 1;
      }
    }