Comment empêcher l'inférence des arguments de type générique avec TypeScript ?
J'ai une API/fonction qui est destinée à être utilisée uniquement avec des arguments de type générique (elle impose la forme d'un argument basé sur un paramètre générique). Je souhaite empêcher l'appel de l'API sans paramètre générique (et donc l'inférence du type à partir des arguments), car cela va à l'encontre du but de ma fonction et sera source de confusion pour les utilisateurs de l'API. Je préférerais que le compilateur impose simplement qu'un argument de type générique soit toujours requis. Par exemple :
function foo<T>(arg: Config<T>) { ... }
Comment puis-je m'assurer que l'argument de type T est toujours spécifié par l'appelant ? c.-à-d. foo<Bar>({ ...})
Réponse #1
Vous pouvez le faire en créant une fonction currifiée, de sorte que vous appelez d'abord une fonction générique qui n'a aucun moyen de déduire votre type générique, et qui crée une fonction avec le type donné intégré à laquelle vous pouvez ensuite passer vos données.
Par exemple :
// Just defining this so the example works
type Config<T> = T;
function foo<T = never>(): (arg: Config<T>) => void {
return (arg: Config<T>) => {
// Do Something here
console.log(arg);
};
}
interface IExample {
foo: string;
}
// Error - the generic type of `foo` has defaulted to `never`
foo()({ foo: 'bar' });
// No error
foo<IExample>()({ foo: 'bar' });
Aire de jeux TypeScript
Malheureusement, cela rend la fonction un peu moins propre, mais autant que je sache, curryfier les fonctions de cette manière est le seul moyen d'obtenir un plus grand degré de contrôle sur la façon dont TypeScript tente d'inférer (ou d'exiger) les types génériques.
Réponse #2
Il ne semble pas y avoir encore de fonctionnalité. C'est tout ce que les documents disent sur les génériques et l'inférence :
function identity<T>(arg: T): T { return arg; } let output = identity<string>("myString"); // type of output will be 'string' let output = identity("myString"); // type of output will be 'string'Remarquez que nous n'avons pas eu à passer explicitement le type dans les crochets (<>); le compilateur a simplement regardé la valeur "myString" et a défini T sur son type.
Et c'est à peu près tout... Aucun indice sur comment l'écrire afin que identity("myString") génère une erreur mais que identity<string>("myString") n'en génère pas.
