Búsqueda de sitios web

Currying con la función bind y cómo tipar correctamente con genéricos en TypeScript


He escrito una función de ordenación y me gustaría vincularle una función de comparación. Desafortunadamente, el compilador de TypeScript me advierte sobre el tipo unknown para la función de comparación.

He intentado buscar en SO: Vincular función a función y buscar en el Manual de TS: bind. Sin embargo, no puedo encontrar ningún problema relacionado.

Y trató de seguir el tipo en el archivo de declaración:

    /**
     * For a given function, creates a bound function that has the same body as the original function.
     * The this object of the bound function is associated with the specified object, and has the specified initial parameters.
     * @param thisArg The object to be used as the this object.
     * @param args Arguments to bind to the parameters of the function.
     */
    bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
    bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;
    bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;
    bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
    bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
    bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;
function sorting<T>(a: T, fn: (v0: T, v1: T) => number,  b: T) {
  return fn(a, b)
}

sorting<number>.bind(null, 1, (a, b) => a + b)
//               ^ Cannot find name 'bind'.(2304)

sorting.bind<null, number, (v0: number, v1: number) => number, [b: number]>(null, 1, (a, b) => a + b)
//^ Argument of type '(b: number) => unknown' is not assignable to parameter of type //'(v0: number, v1: number) => number'.
//  Type 'unknown' is not assignable to type 'number'.(2345)

Campo de Juegos TS

Y todavía no funciona. ¿Me estoy perdiendo de algo aquí? ¿Por qué no puedo bind los argumentos a y fn?


P.D.

Actualmente utilicé una función flecha para aplicar currying a la función de ordenamiento como una solución alternativa.

Respuesta #1

Este es en realidad un problema común, y tan común que se está solucionando en la próxima versión menor de TypeScript (4.7). La solución que se está utilizando se llama expresión de instanciación.

Aquí está su ejemplo:

interface Box<T> {
    value: T;
}

function makeBox<T>(value: T) {
    return { value };
}

Mientras podrías hacer esto:

const makeStringBox = (value: string) => makeBox(value); // makeBox<string>(value: string)

Es bastante desperdicioso, por lo que la versión 4.7 introduce una nueva sintaxis:

const makeStringBox = makeBox<string>; // type parameters passed without calling it!

Esto también significa que puedes pasarlo a sorting antes de vincularlo:

// works in 4.7+ now!
(sorting<number>).bind(null, 1, (a, b) => a + b)

Puedes probar la versión nocturna de TypeScript (4.8+) aquí con este ejemplo.

Artículos relacionados