比方说,我有两个总和类型(此处为F
和G
,其成员之间存在1对1的关系(即strings
与boolean
和{ {1}}与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
和F
分别拥有15/20个成员的情况下很好地起作用?
答案 0 :(得分:1)
联合中的组成部分不是位置,因此您永远不应依赖特定类型在联合中的位置。
如果您使用元组来定义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]