Typescript 重叠类型的类型定义

Typescript 重叠类型的类型定义,typescript,typescript-generics,typing,Typescript,Typescript Generics,Typing,我想为一个函数创建类型定义,该函数接受两个不同类型的对象,但具有一组公共键: function myFunc(left, right, keys) { // simplified: for (const key of keys) { console.log(key, left[key] === right[key]) } return { left, right } } const left = {a: 1, b: 2} const right = {b: 2, c:

我想为一个函数创建类型定义,该函数接受两个不同类型的对象,但具有一组公共键:

function myFunc(left, right, keys) {
  // simplified:
  for (const key of keys) {
    console.log(key, left[key] === right[key])
  }

  return { left, right }
}

const left = {a: 1, b: 2}
const right = {b: 2, c: 3}
myFunc(left, right, ["b"])
这种方法可以工作,但会更改返回的
right
的类型,该类型在函数调用后会在代码中咬我一口:

function myFunc<
  Left,
  Keys extends keyof Left
>(
  left: Left,
  right: Pick<Left, Keys>,
  keys: Keys[],
): {
  left: Left
  right: Pick<Left, Keys>
} {
  // ...
}
函数myFunc<
左边
键从左边延伸
>(
左:左,,
右:选择,
关键字:关键字[],
): {
左:左
右:选择
} {
// ...
}
我希望返回的类型相同:

function myFunc<
  Left,
  Right extends Pick<Left, Keys>,
  Keys extends keyof Left & keyof Right
>(
  left: Left,
  right: Right,
  keys: Keys[]
): { 
  left: Left
  right: Right
}  {
  // ...
}
函数myFunc<
左边
右勾,
“关键点”扩展“左关键点”和“右关键点”
>(
左:左,,
对:对,
关键点:关键点[]
): { 
左:左
对:对
}  {
// ...
}
但是,现在我收到投诉,说类型
左[键]
右[键]
没有重叠。我还没有完全明白


有什么提示或想法吗?

这是一个奇怪的解决方案,但在这个简单的例子中似乎是可行的

函数myFunc<
我选择,
R扩展Pick,
K扩展(R键和L键)>
(左:L,右:R,键:K[]):{left:L,right:R}
{
for(键的常数键){
console.log(键,左[键]==右[键])
}
返回{左,右}
}
const left={a:1,b:2,c:4};
常数右={b:2,c:3,d:5};
//工作:
myFunc(左,右,['b']);
myFunc(左,右,['b','c']);
//错误:类型“”不可分配给类型“b”|“c”。
myFunc(左,右,['a']);
myFunc(左,右,['d']);
myFunc(左,右,['z']);
但是,如果对应于重叠键的值的类型不匹配,则似乎会出现一些问题。这可能是个棘手的解决办法

总的来说,如果可能的话,最好关闭该行的类型检查。

没有解决方案的已知问题
function myFunc<
    L extends Pick<R, (keyof R & keyof L)>,
    R extends Pick<L, (keyof R & keyof L)>,
    K extends (keyof R & keyof L)>
    (left: L, right: R, keys: K[]): { left: L, right: R }
{
    for (const key of keys) {
        console.log(key, left[key] === right[key])
    }

    return { left, right }
}
const left = { a: 1, b: 2, c: 4 };
const right = { b: 2, c: 3, d: 5 };

// Work:
myFunc(left, right, [ 'b' ]);
myFunc(left, right, [ 'b', 'c' ]);

// Error: Type '<>' is not assignable to type '"b" | "c"'.
myFunc(left, right, [ 'a' ]);
myFunc(left, right, [ 'd' ]);
myFunc(left, right, [ 'z' ]);