"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Optimización de una función Curry de TypeScript: de tipos estáticos a tipos variables

Optimización de una función Curry de TypeScript: de tipos estáticos a tipos variables

Publicado el 2024-08-28
Navegar:721

Optimizing a TypeScript Curry Function: From Static Types to Variadic Types

El curry es una técnica de programación funcional que transforma una función con múltiples argumentos en una secuencia de funciones, cada una de las cuales toma un solo argumento. Este enfoque es particularmente útil para crear funciones más modulares y reutilizables, lo que permite la aplicación parcial de argumentos. En TypeScript, implementar una función curry eficiente requiere una gestión cuidadosa de los tipos, especialmente cuando se trata de una cantidad variable de argumentos.

En este artículo, exploraremos dos implementaciones diferentes de una función curry en TypeScript. El primero utiliza interfaces con tipos estáticos, mientras que el segundo adopta un enfoque más flexible utilizando una única interfaz con tipos variados. Analizaremos las diferencias entre estas dos implementaciones y discutiremos las ventajas del enfoque más optimizado.

Implementación inicial: interfaces con tipos estáticos

Definición de las interfaces

En la primera implementación, definí una serie de interfaces para manejar funciones curadas con diferentes números de argumentos. Cada interfaz corresponde a una función con un número específico de argumentos:

interface CurryFunction1 {
    (arg1: T1): R;
}

interface CurryFunction2 {
    (arg1: T1): CurryFunction1;
}

interface CurryFunction3 {
    (arg1: T1): CurryFunction2;
}

interface CurryFunction4 {
    (arg1: T1): CurryFunction3;
}

interface CurryFunction5 {
    (arg1: T1): CurryFunction4;
}

interface CurryFunction6 {
    (arg1: T1): CurryFunction5;
}
Implementando la función Curry

La función curry está definida para utilizar estas interfaces para funciones curry con hasta seis argumentos:

function curry(fn: (arg1: T1, arg2: T2) => R): CurryFunction2;
function curry(fn: (arg1: T1, arg2: T2, arg3: T3) => R): CurryFunction3;
function curry(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => R): CurryFunction4;
function curry(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => R): CurryFunction5;
function curry(fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => R): CurryFunction6;
function curry(fn: Function) {
    return function curried(...args: any[]) {
        if (args.length >= fn.length) {
            return fn(...args);
        } else {
            return (...args2: any[]) => curried(...args, ...args2);
        }
    };
}
Probando la función Curry

Esta función luego se prueba para garantizar que funciona correctamente con diferentes números de argumentos:

function testCurry() {
    const add = (a: number, b: number) => a   b;
    const curriedAdd = curry(add);
    assert(curriedAdd(1)(2) === 3, 'Test curry function with 2 arguments');

    const add3Args = (a: number, b: number, c: number) => a   b   c;
    const curriedAdd3Args = curry(add3Args);
    assert(curriedAdd3Args(1)(2)(3) === 6, 'Test curry function with 3 arguments');
}
Análisis de la Implementación

Si bien esta implementación es clara y típica de TypeScript, tiene algunas limitaciones. En particular, requiere la definición de múltiples interfaces para cada número posible de argumentos, lo que hace que el código sea redundante y más difícil de mantener. Además, manejar más de seis argumentos requeriría agregar más interfaces, lo que aumentaría la complejidad.

Implementación optimizada: interfaz única con tipos variados

Introducción a los tipos variados

Para optimizar la función curry, adopté un enfoque más dinámico utilizando una única interfaz genérica con tipos variados. Este enfoque permite manejar una cantidad arbitraria de argumentos sin necesidad de definir una interfaz separada para cada caso.

Implementación de la función Curry con tipos variados

En esta versión optimizada, la función curry se implementa utilizando una única interfaz genérica que aprovecha los tipos variados de TypeScript para manejar una cantidad arbitraria de argumentos:

type CurryFunction = T extends [infer A, ...infer Rest]
  ? (arg: A) => CurryFunction
  : R;

function curry(fn: (...args: T) => R): CurryFunction {
  return function curried(...args: unknown[]): unknown {
    if (args.length >= fn.length) {
      return fn(...args as T);
    } else {
      return (...args2: unknown[]) => curried(...([...args, ...args2] as unknown[]));
    }
  } as CurryFunction;
}
Beneficios de la implementación optimizada
  1. Complejidad reducida: al utilizar una única interfaz genérica CurryFunction, esta implementación elimina la necesidad de crear múltiples interfaces para cada número posible de argumentos. Esto hace que el código sea más conciso y más fácil de mantener.

  2. Soporte para un número arbitrario de argumentos: aprovechar los tipos variados permite que esta función curre funciones con cualquier número de argumentos sin modificar la implementación. Por tanto, la función es más flexible y adaptable a diversos escenarios.

  3. Escritura mejorada: la escritura dinámica permite a TypeScript inferir con precisión tipos de argumentos, lo que proporciona una verificación de tipos más sólida durante el desarrollo, reduce el riesgo de errores y mejora la finalización del código.

Prueba de la función de curry optimizada

Esta versión de la función curry también se prueba para garantizar que funcione correctamente:

function testCurry() {
    const add = (a: number, b: number) => a   b;
    const curriedAdd = curry(add);
    assert(curriedAdd(1)(2) === 3, 'Test curry function with 2 arguments');

    const add3Args = (a: number, b: number, c: number) => a   b   c;
    const curriedAdd3Args = curry(add3Args);
    assert(curriedAdd3Args(1)(2)(3) === 6, 'Test curry function with 3 arguments');

    const add4Args = (a: number, b: number, c: number, d: number) => a   b   c   d;
    const curriedAdd4Args = curry(add4Args);
    assert(curriedAdd4Args(1)(2)(3)(4) === 10, 'Test curry function with 4 arguments');
}

La optimización de la función curry en TypeScript demuestra cómo se puede mejorar un enfoque basado en interfaces estáticas mediante la adopción de tipos variados. La nueva implementación no sólo reduce la complejidad del código sino que también ofrece mayor flexibilidad y una verificación de tipos más sólida. Este ejemplo resalta la importancia de aprovechar al máximo las capacidades de TypeScript para crear código más limpio, modular y fácil de mantener.

La transición de una estructura con múltiples interfaces a una única interfaz genérica es un gran ejemplo de cómo comprender y aplicar conceptos avanzados de TypeScript puede conducir a soluciones más elegantes y eficientes.

Declaración de liberación Este artículo se reproduce en: https://dev.to/francescoagati/optimizing-a--typescript-curry-function-from-static-types-to-variadic-types-2ma0?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarlo.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3