node.js - TypeScript:捕获在高阶函数中作为参数传递的函数的变量签名
问题描述
我希望一个高阶函数能够捕获可以具有不同签名的传递函数的签名参数。
我不知道这是否可行,但这是我的方法:
type FuncA = (a: string, b: number) => void
type FuncB = (a: string) => void
type Func = FuncA | FuncB
const a: FuncA = (a: string, b: number) => {
console.log('FuncA')
}
const b: FuncB = (a: string) => {
console.log('FuncB')
}
// My higher order function
const c = (func: Func) => {
// do something here...
return (...args: Parameters<typeof func>) => {
func(...args) // Expected 2 arguments, but got 0 or more. ts(2556). An argument for 'a' was not provided.
}
}
我的高阶函数c
无法传递func
似乎 TypeScript 无法区分 type 的不同可能签名的参数Func
。
有谁知道编写这种代码的模式?
谢谢 !
解决方案
这是一个艰难的过程,因为对于extend
另一个函数的函数并不完全符合您的想法。
我们希望由创建的函数c
要求参数与给定的函数相对应。所以我们使用泛型来描述函数。
const c = <F extends Func>(func: F) => {
return (...args: Parameters<F>) => {
func(...args); // still has error
}
}
在这一点上,我们仍然有这个错误,但是当我们调用 时c
,我们会得到一个函数,该函数根据我们是否给出了正确的a
参数b
。
const cA = c(a); // type: (a: string, b: number) => void
cA("", 0);
const cB = c(b); // type: (a: string) => void
cB("");
至于错误,它与一个函数扩展另一个函数的含义有关。尝试更改F extends Func
并F extends FuncA
查看F extends FuncB
会发生什么。我们得到F extends FuncB
一个错误 on c(a)
,但F extends FuncA
我们没有得到一个错误 on c(b)
。嗯?
如果您从回调的角度考虑它,那是有道理的。可以传递一个需要比预期更少的参数的函数,但不能传递一个需要更多参数的函数。但是我们是实现回调的人,所以这给我们带来了问题。如果我们type Func
使用没有参数的函数进行扩展,则空数组 fromParameters<F>
不足以调用任何一种类型。
我们必须让我们的泛型依赖于参数。
type AP = Parameters<FuncA> // type: [a: string, b: number]
type BP = Parameters<FuncB> // type: [a: string]
type Args = AP | BP;
const c = <A extends Args>(func: (...args: A) => void) => {
return (...args: A) => {
func(...args) // no error
}
}
推荐阅读
- python - Python 'No module named' 错误;“包”不是包
- c# - 时间:2019-01-03 标签:c#regex获取start to end char的每个实例
- rabbitmq - 在单个队列上运行多个消费者
- javascript - 内联函数内部无法访问打字稿方法变量
- java - 线程 1 每秒填充一次映射,线程 2 每 60 秒持久化一次条目
- django - Django 模型方法与自定义管理器
- javascript - 重复时CSS淡入/淡出无法正常工作
- c - 假设 UTF-8 将 =C3=B6 转换为 ö
- sql - 根据 Id 分区的日期列获取列的第一个值
- python - 使用 pipenv 安装 Pillow 的问题