Search code examples
typescriptfunctionoverloadingtyping

Return type 'never' if an optional parameter is given to be a specific value


I have a function that takes an optional boolean argument that defaults to false. When the argument is false, the function returns a string. When the argument is true, the function should return type never.

Here's what I tried:

function example(arg: true): never;
function example(arg = false): string {
  //...
}

This feels like it should work: arg is inferred to have a boolean type, and when it is not passed or passed as false, example returns string. When it is passed as true, the overload kicks in and example returns never.

However, this doesn't work at all. TypeScript gives arg the type true and makes it required and makes example always return never.

I also tried this craziness, and got closer:

function example(arg: false): string;
function example(arg: true): never;
function example(arg: boolean): string | never;
function example(arg = false): string | never {
  //...
}

However the compiler still doesn't consider arg to be optional.


Solution

  • This seems to work:

    function example(arg: true): never;
    function example(arg?: false): string;
    function example(arg: boolean): string;
    function example(arg: boolean = false): never | string {
        if (!arg) {
            return 'foo';
        }
    
        throw new Error();
    }
    
    const foo = example(true); // typeof foo is never
    const bar = example(false); // typeof bar is string
    const baz = example(); // typeof baz is string
    

    Link to playground