"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Optimisation d'une fonction TypeScript Curry : des types statiques aux types variadiques

Optimisation d'une fonction TypeScript Curry : des types statiques aux types variadiques

Publié le 2024-08-28
Parcourir:558

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

Currying est une technique de programmation fonctionnelle qui transforme une fonction avec plusieurs arguments en une séquence de fonctions, chacune prenant un seul argument. Cette approche est particulièrement utile pour créer des fonctions plus modulaires et réutilisables, permettant une application partielle des arguments. Dans TypeScript, l'implémentation d'une fonction curry efficace nécessite une gestion minutieuse des types, en particulier lorsqu'il s'agit d'un nombre variable d'arguments.

Dans cet article, nous explorerons deux implémentations différentes d'une fonction curry dans TypeScript. Le premier utilise des interfaces avec des types statiques, tandis que le second adopte une approche plus flexible utilisant une interface unique avec des types variadiques. Nous analyserons les différences entre ces deux implémentations et discuterons des avantages de l’approche plus optimisée.

Implémentation initiale : interfaces avec des types statiques

Définir les interfaces

Dans la première implémentation, j'ai défini une série d'interfaces pour gérer les fonctions au curry avec un nombre variable d'arguments. Chaque interface correspond à une fonction avec un nombre précis d'arguments :

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;
}
Implémentation de la fonction Curry

La fonction curry est définie pour utiliser ces interfaces pour curry des fonctions avec jusqu'à six arguments :

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);
        }
    };
}
Test de la fonction curry

Cette fonction est ensuite testée pour s'assurer qu'elle fonctionne correctement avec différents nombres d'arguments :

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');
}
Analyse de la mise en œuvre

Bien que cette implémentation soit claire et typique de TypeScript, elle présente certaines limites. Cela nécessite notamment la définition de plusieurs interfaces pour chaque nombre possible d’arguments, ce qui rend le code redondant et plus difficile à maintenir. De plus, gérer plus de six arguments nécessiterait l’ajout de plus d’interfaces, ce qui augmenterait la complexité.

Implémentation optimisée : interface unique avec des types variadiques

Introduction aux types variadiques

Pour optimiser la fonction curry, j'ai adopté une approche plus dynamique utilisant une seule interface générique avec des types variadiques. Cette approche permet de gérer un nombre arbitraire d'arguments sans avoir besoin de définir une interface distincte pour chaque cas.

Implémentation de la fonction Curry avec des types variadiques

Dans cette version optimisée, la fonction curry est implémentée à l'aide d'une seule interface générique qui exploite les types variadiques de TypeScript pour gérer un nombre arbitraire d'arguments :

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;
}
Avantages de la mise en œuvre optimisée
  1. Complexité réduite : en utilisant une seule interface générique CurryFunction, cette implémentation élimine le besoin de créer plusieurs interfaces pour chaque nombre possible d'arguments. Cela rend le code plus concis et plus facile à maintenir.

  2. Prise en charge d'un nombre arbitraire d'arguments : L'exploitation des types variadiques permet à cette fonction d'étudier des fonctions avec n'importe quel nombre d'arguments sans modifier l'implémentation. La fonction est ainsi plus flexible et adaptable à différents scénarios.

  3. Saisie améliorée : la saisie dynamique permet à TypeScript de déduire avec précision les types d'arguments, fournissant une vérification de type plus forte pendant le développement, réduisant le risque d'erreurs et améliorant l'achèvement du code.

Test de la fonction curry optimisée

Cette version de la fonction curry est également testée pour garantir son bon fonctionnement :

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

L'optimisation de la fonction curry dans TypeScript montre comment une approche basée sur des interfaces statiques peut être améliorée en adoptant des types variadiques. La nouvelle implémentation réduit non seulement la complexité du code, mais offre également une plus grande flexibilité et une vérification de type plus renforcée. Cet exemple souligne l'importance d'exploiter pleinement les capacités de TypeScript pour créer un code plus propre, plus modulaire et maintenable.

La transition d'une structure avec plusieurs interfaces à une seule interface générique est un excellent exemple de la façon dont la compréhension et l'application des concepts TypeScript avancés peuvent conduire à des solutions plus élégantes et efficaces.

Déclaration de sortie Cet article est reproduit sur : https://dev.to/francescoagati/optimizing-a-typescript-curry-function-from-static-types-to-variadic-types-2ma0?1 En cas d'infraction, veuillez contacter study_golang @163.com supprimer
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3