42 votes

Pourquoi le mot clé infer est nécessaire dans Typescript ?

Pourquoi les gens de Typescript ont-ils créé le infer mot-clé ? Selon le documents Voici un exemple de la façon dont vous pouvez l'utiliser :

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

Je ne comprends pas pourquoi cela est nécessaire. Pourquoi ça ne peut pas être juste :

type ReturnType<T> = T extends (...args: any[]) => R ? R : any;

Pourquoi ça ne marche pas ? Pourquoi est-ce que le infer mot-clé nécessaire ?

39voto

kaya3 Points 17037

Considérons le code suivant :

interface Example {
    foo: string
}

type GenericExample<T> = T extends Examlep ? 'foo' : 'bar';

Ce code devrait entraîne une erreur de compilation, car Examlep est mal orthographié ; il n'existe pas de type nommé Examlep et il est évident que le programmeur voulait écrire Example ici.

Maintenant, imaginez le infer Le mot clé n'est pas nécessaire dans un extends d'une clause de type conditionnel. Alors le code ci-dessus ne donnerait pas d'erreur de compilation ; il verrait qu'il n'y a pas de type nommé Examlep de déduire de quel type il s'agit, puis (puisque Examlep n'a pas de contraintes) observe que T s'étend en effet Examlep pour le type déduit.

Dans ce cas, GenericExample<T> sería toujours être 'foo' indépendamment de ce que T est, et il n'y aurait pas d'erreur de compilation pour informer le programmeur de son erreur. Ce serait la mauvaise chose à faire pour le compilateur, presque tout le temps.

34voto

ford04 Points 112

Avec infer le compilateur s'assure que vous avez déclaré toutes les variables de type explicitement . Il est possible de définir des variables de type, par exemple :

  • après infer au sein de la extends clause d'un type conditionnel R en T extends (...args: any[]) => infer R
  • sur le côté gauche de la déclaration de type T en ReturnType<T> = ...
  • dans le cadre d'un type de carte K en type Mapped<T> = { [K in keyof T]: ... }

L'utilisation de paramètres de type non déclarés peut désormais entraîner une erreur de compilation. Sans infer le compilateur ne saurait pas, si vous voulez introduire une variable de type supplémentaire (disons R ) qui doit être déduite, ou si R est juste une erreur de frappe accidentelle/typo.

type R = { a: number }

type MyType<T> = T extends infer R ? R : never; // infer new variable R from T
type MyType2<T> = T extends R ? R : never; // compare T with above type R
type MyType3<T> = T extends R2 ? R2 : never; // error, R2 undeclared

type T1 = MyType<{b: string}> // T1 is { b: string; }
type T2 = MyType2<{b: string}> // T2 is never

Terrain de jeux

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X