У меня есть функция высшего порядка, например, в ванильных JS, как это:Как правильно ввести функцию высшего порядка
function log(fn) {
return (...args) => {
console.log("Calling", fn.name);
return fn(...args);
}
}
И используются так:
let name;
const setName = log((newName) => {
name = newName;
});
setName("Hello"); // output "Calling setName"
Как правильно ввести это в TS, так что setName
имеет правильную сигнатуру функции? Значение:
setName("hello") // OK
setName() // Error, missing arg
setName(123) // Error, number not string
То, что я придумал до сих пор:
function log<F extends Function>(fn: F): F {
return (...args: any[]) => {
console.log("Calling", fn.name);
return fn(...args);
}
}
let name;
const setName = log((newName: string) => {
name = newName;
});
Который работает так, как я хочу (я получаю проверку на setName
тип аргумента), но я получаю ошибку компиляции на log
функция возврата:
Error: TS2322:Type '(...args: any[]) => any' is not assignable to type 'F'.
Даже если я использую <F extends (...args: any[]) => any>
я получаю ту же ошибку. В принципе, я не знаю, как заставить возвращаемую функцию удовлетворять общему типу F
.
Как я могу это сделать?
Спасибо, я не думал об использовании перегрузок функций, подобных этому. – Aaron
Я отредактировал с идеей другого автора. Тип 'Функция' слишком широк. Ваша завернутая функция должна иметь тип: '(... args: any []) => any'. – Paleo
Интересно, я попробовал 'F extends (...args: any []) => any' с моим исходным кодом, и по какой-то причине он по-прежнему не позволял мне возвращаться даже с такой точной сигнатурой, а 'как F' не работал с' F extends Function'. Честно говоря, я не понимаю, почему это другое, но оно работает. – Aaron