javascript - 如何限制函数签名只接受特定的类型参数对

标签 javascript typescript

假设我有两个求和类型(FG),它们的成员是一对一的关系(即,stringsboolean 一起使用,numberobject 一起使用)。

我想定义一个函数 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

但是随着类型族变得越来越大,这种方法很快就变得不可扩展了。在 FG 各有 15/20 个成员的情况下,是否有一种不同的方法可以很好地工作?

最佳答案

联合中的成分不是位置性的,因此您永远不应依赖特定类型在联合中的位置。

如果您使用元组来定义 FG,那么我们可以在剩余参数中使用元组来获取正确的签名并使用映射类型来合并两个元组合并为一个元组:

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

play

要恢复原始联合,您始终可以使用 F[number]G[number]

关于javascript - 如何限制函数签名只接受特定的类型参数对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58076090/

相关文章:

typescript - 键入静态对象的值,同时保留其键类型不变

typescript - Typescript:如何实现这种类型的递归?

javascript - MongoDB 对大容量数据进行排序

javascript - 如何在 Javascript 中公开对象的数据?

javascript - 使用 JQuery 淡出并重新加载

angular - ag 网格分页不起作用,最初使服务器调用两次

javascript - 通过代码设置应用程序注册 (Azure AD)?

javascript - 所有浏览器中无响应的脚本错误 - 需要识别脚本

javascript - Angular 6 使用管道将字符串转换为 Html

reactjs - 类型 'string' 不可分配给类型 '"菜单“| "selectedMenu"| 未定义”