如何设置函数的类型,该函数作为函数参数,可以有任何参数和任何返回值



我想用typescript写一个debounce函数。我的代码如下:

function debounce(fn: Function, time: number): Function {
// ...
}

然后,我的eslint告诉我不要使用Function作为类型。以下是原文:

不要使用Function作为类型。Function类型接受任何类似函数的值。它在调用函数时不提供类型安全,这可能是bug的常见来源。它还接受类声明之类的东西,这些声明将在运行时抛出,因为它们不会被new调用。

如果你希望函数接受某些参数,你应该显式地定义函数的形状。

这就是问题所在,有什么建议吗?

==================== 一些更新 ==================================

如果使用javascript,我的代码将是:

function debounce(fn, time) {
let timer
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => fn(...args), time)
}
}

给定您的实现,从debounce()返回的函数不返回有用的结果;这意味着我们不关心fn参数的返回类型是什么。在这种情况下,我可能会使debounce()成为一个泛型函数,其类型参数A作为与fn的参数相对应的rest元组。这样的:

function debounce<A extends any[]>(fn: (...a: A) => void, time: number) {
let timer: number;
return function (...args: A) {
clearTimeout(timer)
timer = setTimeout(() => fn(...args), time)
}
}

类型(...a: A) => void是一个函数类型表达式,意思是"该函数的参数数组为A类型,并且返回void,因此它的返回类型将被忽略"。

如果你检查debounce()的类型,它看起来像这样:

/* function debounce<A extends any[]>(
fn: (...a: A) => void, time: number
): (...args: A) => void */

它接受一个(...a: A) => void类型的函数,并返回一个相同类型的函数。


让我们确保它工作:

function log(x: string) {
console.log(x);
}
const debouncedLog = debounce(log, 1000);
debouncedLog("hello");
debouncedLog(100); // error, doesn't accept a number
debouncedLog("there");
// just "there" is logged

你可以看到编译器抱怨debouncedLog(100),因为100不能赋值给string,而其他调用可以正常工作。

Playground链接到代码

我建议你看看TypeScript的实用程序类型,比如Parameters<Type>ThisParameterType<Type>。他们是我用于防反跳的打印稿实现函数使返回的函数匹配输入函数的签名。

至于我如何指定函数参数,我使用了这样的泛型:

const debounce = function<T extends (...args: any) => any> (fn: T, delay: number) {

相关内容

  • 没有找到相关文章

最新更新