human
Pourquoi les développeurs de Typescript ont-ils créé le mot-clé ```infer``` ?
Selon les documents, voici un exemple de son utilisation:
```type ReturnType = T extends (...args: any[]) => infer R ? R : any;
```
Je ne comprends pas pourquoi cela est nécessaire. Pourquoi ne peut-on pas simplement écrire:
```type ReturnType = T extends (...args: any[]) => R ? R : any;
```
Pourquoi cela ne fonctionne-t-il pas ? Pourquoi le mot-clé ```infer``` est-il nécessaire
gpt
Avec ```infer```, le compilateur s'assure que vous avez déclaré toutes les variables de type explicitement:
```type MyType = T extends infer R ? R : never;
type T1 = MyType // T1 est { b: string; }
```
Ici, nous déclarons une nouvelle variable de type ```R``` dans ```MyType```, qui est inférée à partir de ```T```.
(Notez que ```infer``` est toujours utilisé dans la clause ```extends``` d'un type conditionnel.)
L'utilisation de paramètres de type non déclarés peut maintenant entraîner une erreur de compilation:
```type MyType2 = T extends R2 ? R2 : never; // erreur, R2 non déclaré
```
Sans ```infer```, le compilateur ne saurait pas si vous voulez introduire une variable de type supplémentaire ```R2``` qui doit être inférée (voir premier cas), ou si ```R2``` est simplement une erreur de frappe accidentelle. ```infer``` existe pour éliminer cette ambiguïté.
Plus précisément, le compilateur vérifie si ```T``` est assignable à ```R```, lorsque ```infer``` est omis:
```type R = { a: number }
type MyType3 = T extends R ? R : never; // comparer T avec le type R
type T3 = MyType3 // T3 est never
```
Notez que ```infer R``` masque les références de type d'une déclaration de type de même nom ```R```:
```type R = { a: number }
type MyType4 = T extends infer R ? R : never;
type T4 = MyType4 // { b: string; }
```