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?
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");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With