javascript - 如何将函数签名限制为仅接受特定的类型参数对
问题描述
假设我有两种求和类型(这里是) F
,G
它们的成员是一对一的关系(即,strings
与boolean
和number
一起object
)。
我想定义一个函数F -> G -> something
,其签名只允许某些参数对。
我可以通过函数重载很容易地做到这一点,如下所示:
type F = string | number
type G = boolean | object
function f(x: string, y: boolean): any
function f(x: number, y: object): any
function f(x: F, y: G): any {
return;
}
f('a', true) // OK
f(1, { x: 1 }) // OK
f('a', { x: 1 }) // NOT OK
但是随着类型族的增长,这种方法很快变得无法扩展。有没有一种不同的方法可以在每个成员有 15 / 20 个成员的情况下很好地工作F
?G
解决方案
联合中的成分不是位置的,因此您永远不应依赖联合中特定类型的位置。
如果您使用元组进行定义F
,G
那么我们可以在剩余参数中使用元组来获取正确的签名并使用映射类型将两个元组合并为元组联合:
type F = [string, number]
type G = [boolean, object]
type Merge<F extends any[], G extends any[]> = {
[P in keyof F]: Parameters<(x: F[P], y: G extends Record<P, any> ? G[P]: never) => void> // [F[P], G[P]] would work as well byt
}[number]
type FG = Merge<F, G> // this is [string, boolean] | [number, object]
function f(...a: Merge<F, G>): any {
return;
}
f('a', true) // OK
f(1, { x: 1 }) // OK
f('a', { x: 1 }) // NOT OK
要取回原来的工会,你总是可以使用F[number]
和G[number]
推荐阅读
- assembly - 为什么编译器要重新计算另一个寄存器中已经存在的值?
- discord.py-rewrite - 'VoiceState' 对象没有属性 'voice_channel'
- android - 为什么广播接收器在重新启动时不起作用?
- python - 在 Lambda DynamoDB 函数中添加限制
- ios - IOS 14 AVPlayer 在模拟器上播放,但不在真实设备上
- elasticsearch - 弹性搜索 kubernetes 数据磁盘使用量猛增
- c# - 上传 excel 文件并在 aspnet core 中添加手动值
- mysql - MySQL CLI:未知选项:enable-cleartext-plugin
- php - 在 laravel 控制器中使用特征
- azure - Azure Kubernetes - 副本与 HPA?