Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript overload considers only one of the overloaded signatures

Tags:

typescript

I'm trying to apply typescript's method overloading on a class method, for the filter class method.

class Vector<T> {
    static of<T>(vals: T[]): Vector<T> {
        return undefined;
    }
    // filter<U extends T>(fn:(x:T)=>x is U): Vector<U>;
    filter(fn:(x:T)=>boolean): this {
        return undefined;
    }
}

const v1 = Vector.of([1,2,3]).filter(x=>x>1);

This works fine, until the commented line is uncommented.

When uncommenting that line, we get the error:

ttt.ts(12,38): error TS2345: Argument of type '(x: number) => boolean' is not assignable to parameter of type '(x: number) => x is number'.
  Signature '(x: number): boolean' must be a type predicate.

So it seems typescript (2.7.2) ignores the overload and picks only one of the type definitions for filter, which I don't understand. This pattern of having the overloaded filter is relatively known, and used by typescript's own es5.d.ts, in addition overloading is also supported for classes so I would expect it to be supported also in this case?

like image 425
Emmanuel Touzery Avatar asked Oct 29 '25 01:10

Emmanuel Touzery


1 Answers

The problem is that for functions with an implementation, the last signature is the implementation signature and is not publicly available:

class Vector<T> {
    static of<T>(vals: T[]): Vector<T> {
        return undefined;
    }
    filter<U extends T>(fn:(x:T)=>x is U): Vector<U>;
    filter(fn:(x:T)=>boolean): this 
    // Private signature 
    filter(fn:(x:T)=>boolean): this {
        return undefined;
    }
}
const v1 = Vector.of([1,2,3]).filter(x=>x>1);
const v2 = Vector.of([1,2,3, ""]).filter((x) : x is string =>typeof x === "string");
like image 87
Titian Cernicova-Dragomir Avatar answered Oct 30 '25 22:10

Titian Cernicova-Dragomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!