В JavaScript обычно используется функция, которая может быть вызвана более чем одним способом - например. с несколькими позиционными аргументами или один объект опций или некоторая комбинация из двух.
Я пытаюсь разобраться, как комментировать это.
Один из способов, которым я пытался, заключался в том, чтобы аннотировать остальные args как объединение различных возможных кортежей:
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);
Вышеприведенный фрагмент изобретателен; Я мог бы, вероятно, просто использовать (...args: Array<string | number>)
в этом примере, но для более сложных сигнатур (например, с участием объекта типизированных опций, который может быть один или с предшествующими аргументами) было бы полезно иметь возможность определить точный конечный набор возможных вызовов подписи.
Но вышесказанное не проверяет тип. Вы можете увидеть путаницу ошибок в tryflow.
Я также попытался напечатать эту функцию как объединение отдельных целых функций defs, но тоже не работал:
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);
Как мне подойти к типам аннотирующих функций с несколькими возможными сигнатурами вызова? (Или многосимволы считаются анти-шаблонами в потоке, и я просто не должен делать этого вообще - в этом случае, какой рекомендуемый подход для взаимодействия с сторонними библиотеками, которые это делают?)