Search code examples
typescriptfunctional-programmingtypescript-genericspointfree

Generic types with point-free functions


Supose I have next funcion:

function cast<T>(v: any): T {
    return v as T;
}

Now, I have an array what I want to cast using map:

const arr = [1, 3, 5];

// works
arr.map(value => cast<number>(value));

// but I want
arr.map(cast<number>);

Is it possible? Can I pass generic on point-free map?


Solution

  • Actually, the method map from the Array prototype is generic.

    Array<T>.map<U>(callback: (value: T, index: number, array: T[]) => U): U[]
    

    So, by using your cast function with any type argument (like using it as a pointer-free) returns unknown. Totally expected.

    You can cast your array like so

    const arr = [1, 3, 5];
    const re = arr.map<string>(cast);
    

    Here is an interesting post about this.


    I was reading this post months later and another idea just flashed in my mind.
    Another solution could be a function wrapper to pass the type argument to the cast function explicitly.

    type Fn<T> = (element: any) => T;
    
    const cast = <T>(element: any): T => {
        return element as T;
    }
    
    const caster = <T>() => {
        return cast as Fn<T>;
    }
    
    const dut: any[] = [1, 2, 3, 4, 5, 6];
    const casted = dut.map(caster<number>());
    
    // casted is of type number[]
    

    Although the main solution is still the best, this approach can solve some situations where the target API does not offer any overload to infer the type.

    Hope it helps.