"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Otimizando uma função TypeScript Curry: de tipos estáticos a tipos variáveis

Otimizando uma função TypeScript Curry: de tipos estáticos a tipos variáveis

Publicado em 2024-08-28
Navegar:511

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

Currying é uma técnica de programação funcional que transforma uma função com múltiplos argumentos em uma sequência de funções, cada uma recebendo um único argumento. Esta abordagem é particularmente útil para criar funções mais modulares e reutilizáveis, permitindo a aplicação parcial de argumentos. No TypeScript, a implementação de uma função curry eficiente requer um gerenciamento cuidadoso de tipos, especialmente ao lidar com um número variável de argumentos.

Neste artigo, exploraremos duas implementações diferentes de uma função curry no TypeScript. O primeiro utiliza interfaces com tipos estáticos, enquanto o segundo adota uma abordagem mais flexível utilizando uma única interface com tipos variados. Analisaremos as diferenças entre essas duas implementações e discutiremos as vantagens da abordagem mais otimizada.

Implementação Inicial: Interfaces com Tipos Estáticos

Definindo as Interfaces

Na primeira implementação, defini uma série de interfaces para lidar com funções curried com números variados de argumentos. Cada interface corresponde a uma função com um 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 a Função Curry

A função curry é definida para usar essas interfaces para funções curry com até 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);
        }
    };
}
Testando a função Curry

Esta função é então testada para garantir que funciona corretamente com 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álise da Implementação

Embora esta implementação seja clara e típica do TypeScript, ela tem algumas limitações. Notavelmente, requer a definição de múltiplas interfaces para cada número possível de argumentos, tornando o código redundante e mais difícil de manter. Além disso, lidar com mais de seis argumentos exigiria a adição de mais interfaces, aumentando a complexidade.

Implementação Otimizada: Interface Única com Tipos Variádicos

Introdução aos tipos variáveis

Para otimizar a função curry, adotei uma abordagem mais dinâmica usando uma única interface genérica com tipos variados. Esta abordagem permite lidar com um número arbitrário de argumentos sem a necessidade de definir uma interface separada para cada caso.

Implementando a Função Curry com Tipos Variádicos

Nesta versão otimizada, a função curry é implementada usando uma única interface genérica que aproveita os tipos variados do TypeScript para lidar com um número arbitrário 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;
}
Benefícios da implementação otimizada
  1. Complexidade reduzida: Ao usar uma única interface genérica CurryFunction, esta implementação elimina a necessidade de criar múltiplas interfaces para cada número possível de argumentos. Isso torna o código mais conciso e mais fácil de manter.

  2. Suporte para um número arbitrário de argumentos: O aproveitamento de tipos variados permite que esta função curry funções com qualquer número de argumentos sem modificar a implementação. A função é, portanto, mais flexível e adaptável a vários cenários.

  3. Digitação aprimorada: A digitação dinâmica permite que o TypeScript infira tipos de argumentos com precisão, fornecendo verificação de tipo mais forte durante o desenvolvimento, reduzindo o risco de erros e melhorando o preenchimento do código.

Testando a função Curry otimizada

Esta versão da função curry também é testada para garantir que funciona corretamente:

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');
}

A otimização da função curry no TypeScript demonstra como uma abordagem baseada em interfaces estáticas pode ser melhorada com a adoção de tipos variados. A nova implementação não apenas reduz a complexidade do código, mas também oferece maior flexibilidade e verificação de tipo mais forte. Este exemplo destaca a importância de aproveitar totalmente os recursos do TypeScript para criar código mais limpo, modular e de fácil manutenção.

A transição de uma estrutura com múltiplas interfaces para uma única interface genérica é um ótimo exemplo de como compreender e aplicar conceitos avançados de TypeScript pode levar a soluções mais elegantes e eficientes.

Declaração de lançamento Este artigo está reproduzido em: https://dev.to/francescoagati/optimizing-a-typescript-curry-function-from-static-types-to-variadic-types-2ma0?1 Se houver alguma violação, entre em contato com study_golang @163.com excluir
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3