gpt4 book ai didi

typescript - 如何正确输入高阶函数

转载 作者:行者123 更新时间:2023-12-02 17:21:23 25 4
gpt4 key购买 nike

我有一个高阶函数,例如在 vanilla 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 .

我该怎么做?

最佳答案

函数重载

Function overloads可以使用。这是一种将定义与实现分开的方法:

function log<F extends Function>(fn: F): F
function log(fn: Function) {
return (...args) => {
console.log("Calling", fn.name);
return fn(...args);
}
}

我喜欢重载版本,因为当模块作为预编译的 NPM 包分发时,它有助于生成 TypeScript 定义。

使用类型断言 as F

Function 类型太宽。您的包装函数必须是以下类型的子类型:(...args: any[]) => any

你可以使用 as F 来告诉 TypeScript 对返回的函数有信心:

function log<F extends (...args: any[]) => any>(fn: F): F {
return ((...args: any[]) => {
console.log("Calling", fn.name);
return fn(...args);
}) as F
}

使用类型断言as any

相同的实现,但我们可以使用 Functionas any 而不是 (...args: any[]) => anyas F(参见 Louis 的回答)。

关于typescript - 如何正确输入高阶函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42372219/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com