TypeScript: False argument error for function overloads -- TS Limitation?

Viewed 233

I wanted to create a wrapper for the jQuery $ method but TypeScript kept throwing errors. I isolated the problem as following:

function x(q: string): number;
function x(q: number): number;
function x(q: string | number) { return (typeof q === 'string') ? parseInt(q): q; }
function xx(qq: string | number) {
    return x(qq);
}

which gives me:

Error   TS2769  (TS) No overload matches this call.
  Overload 1 of 2, '(q: string): number', gave the following error.
    Argument of type 'string | number' is not assignable to parameter of type 'string'.
      Type 'number' is not assignable to type 'string'.
  Overload 2 of 2, '(q: number): number', gave the following error.
    Argument of type 'string | number' is not assignable to parameter of type 'number'.
      Type 'string' is not assignable to type 'number'. D:\project\Scripts\ts (tsconfig or jsconfig project)    D:\project\Scripts\ts\Components\JQueryExtensions.ts    13  Active

As screenshot:

enter image description here

I understand the error message. I also know how to avoid the error (as any). My question is: Shouldn't TypeScript notice that qq and q are actually of the same type and thus allow this code? Is this a known limitation of TypeScript? Btw, I am using TS 3.6.

1 Answers

Actually only first two x() declarations are visible, the implementation itself is considered invisible. If you want to make it also visible, you should add it explicitly to the overload list, like:

function x(q: string): number;
function x(q: number): number;
function x(q: string | number): number;
function x(q: string | number) { return (typeof q === 'string') ? parseInt(q): q; }
function xx(qq: string | number) {
    return x(qq);
}

But, in this case the first two overloads doesn't make sense, as well as the new one, because it matches the implementation, you can just remove the overloads.

function x(q: string | number) { return (typeof q === 'string') ? parseInt(q): q; }
function xx(qq: string | number) {
    return x(qq);
}
Related