Typescript typing errors for overloads with optional parameters

Viewed 22

I have two typescript functions with the same signature like so:

function a(x?:undefined):undefined
function a(x:string):string
function a(x?:string|undefined):string|undefined{
    return x; // the real function is less trivial
}

function b(x?:undefined):undefined
function b(x:string):string
function b(x?:string|undefined):string|undefined{
    return a(x)
}

and typescript complains about the call to a(x) with the error message:

Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.ts(2345)

(4, 10): The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.

I've tried a ton of similar variants on the signatures, with no luck, and the only way I've found to avoid this error is completely absurd -- by replacing a(x) with typeof x === "undefined" ? a(x) : a(x) which unnecessarily introduces a ternary expression at runtime and is confusing to read.

What is the proper way of calling a(x) from inside b in this case?

1 Answers

Apparently the trick is to add an additional signature to a like so:

function a():undefined
function a(x:string):string
function a(x?:string):string|undefined
function a(x?:string):string|undefined{
    return x; // the real function is less trivial
}

function b():undefined
function b(x:string):string
function b(x?:string):string|undefined{
    return a(x)
}
Related