En JavaScript, il est courant d'avoir une fonction qui peut être appelée à plus d'un titre – par exemple, avec quelques arguments de position ou un seul objet d'options ou une combinaison des deux.
J'ai essayé de travailler sur la façon d'annoter cette.
Une façon que j'ai essayé était pour annoter reste args comme une union de différentes possibles des n-uplets:
type Arguments =
| [string]
| [number]
| [string, number]
;
const foo = (...args: Arguments) => {
let name: string;
let age: number;
// unpack args...
if (args.length > 1) {
name = args[0];
age = args[1];
} else if (typeof args[0] === 'string') {
name = args[0];
age = 0;
} else {
name = 'someone';
age = args[1];
}
console.log(`${name} is ${age}`);
};
// any of these call signatures should be OK:
foo('fred');
foo('fred', 30);
foo(30);
L'extrait ci-dessus est artificiel; je pourrais probablement juste utiliser (...args: Array<string | number>)
dans cet exemple, mais pour les plus complexes des signatures (par exemple, impliquant un typée objet d'options qui peuvent être seuls ou avec l'accord préalable args) il serait utile de pouvoir définir un état précis, ensemble fini d'appel possible de signatures.
Mais le ci-dessus n'est pas de type case. Vous pouvez voir un tas de confusion des erreurs dans tryflow.
J'ai aussi essayé en tapant la fonction elle-même, en tant qu'union de séparer intégralité de la fonction defs, mais qui n'a pas de travail , soit:
type FooFunction =
| (string) => void
| (number) => void
| (string, number) => void
;
const foo: FooFunction = (...args) => {
let name: string;
let age: number;
// unpack args...
if (args.length > 1) {
name = args[0];
age = args[1];
} else if (typeof args[0] === 'string') {
name = args[0];
age = 0;
} else {
name = 'someone';
age = args[1];
}
console.log(`${name} is ${age}`);
};
// any of these call signatures should be OK:
foo('fred');
foo('fred', 30);
foo(30);
Comment devrais-je m'approche de type annotation des fonctions avec plusieurs d'appel possible de signatures? (Ou multi-signatures considéré comme un anti-modèle en Flux, et je ne devrais pas faire ça à tous – en ce cas, qu'est-ce que l'approche recommandée pour l'interaction avec des bibliothèques tierces que faire?)