#typescript #generics #types #functional-programming #typescript-generics
#typescript #дженерики #типы #функциональное программирование #typescript-дженерики
Вопрос:
Как мне указать TypeScript подключить тип параметра fn
выше к типу параметра ...args
ниже??
/**
* @template F
* @param {(...o: Parameters<F>) => boolean} fn
*/
function not(fn) {
return (
/**
* @param {Parameters<F>} args
* @returns {boolean}
*/
(...args) => {
return !fn(...args);
}
);
}
Ответ №1:
Поскольку вы используете JSDoc, я думаю, я бы написал это так:
/**
* @template {any[]} A
* @param {(...args: A)=>boolean} fn
*/
function not(fn) {
return (
/**
* @param {A} args
* @returns {boolean}
*/
(...args) => {
return !fn(...args);
});
}
Дело в том, чтобы быть универсальным в A
, тип args
вместо в F
котором предположительно является типом функции.
Вы можете протестировать ее:
/**
* @param {string} x
* @param {number} y
*/
function hmm(x, y) {
return x.length === y;
}
const notHmm = not(hmm);
notHmm("", 2)
notHmm(123, "") // error!
// --> ~~~
// Argument of type 'number' is not assignable to parameter of type 'string'.(2345)
notHmm(); // error!
// Expected 2 arguments, but got 0.(2554)
Выглядит хорошо.
Игровая площадка ссылка на код
В TS это было бы
function not<A extends any[]>(
fn: (...args: A) => boolean
) {
return (
(...args: A) => {
return !fn(...args);
});
}
Комментарии:
1. Я не хочу использовать
any
, я пытаюсь позволить TypeScript убедиться, что моя обернутая функция имеет те же типы параметров, что и функция, которую она переносит.2. Да, это то, что делает этот ответ. Вы не «используете
any
» в том смысле, о котором вы могли бы подумать.3. О, я вижу, что вы сделали, вы просто расширили any[] . Ну, это в основном работает, за исключением того, что TypeScript сообщает мне, что аргумент теперь необязательный. Итак, если f принимает
string, number
, not(f) принимаетstring?, number?
4. Именно так работает JS с проверкой TS . Не уверен, что вы хотите, чтобы я с этим поделал. На самом деле, я не могу воспроизвести это , поэтому вы можете уточнить свою проблему (хотя, если это просто то, как работает JS-in-TS, я не могу ничего сделать, кроме как посочувствовать вам)
5. Оказывается, необязательная вещь заключалась в том, что я использовал
@type
прямо перед параметром, а@param
не прямо перед функцией, которая исправляет ошибку-необязательность. Итак, ваш ответ просто великолепен.