如何要求参数是一个通用的严格扩展部分

How to require parameter to be a generic strictly extending a partial

我正在尝试获得直观的结果,即说明一些泛型 P 是 O 的偏音。

declare function foo<O, P extends Partial<O>>(obj: O, part: P): P

但是,这允许键不是 O for P

// no errors
foo({a:2},{a:100, b:2})

这个也不行

declare function foo<O, P>(obj: O, part: P & Partial<O>): P

这个版本有效

declare function foo<O, P>(obj: O, part: Partial<O>): unknown

// correct, Typescript complains that `b` is not allowed
foo({a:2},{a:100, b:2})

然而 return 类型不能泛型 P.

是否存在将 P 限制为 O 中的键并满足通用要求的解决方案?

-- 更新

对于任何感兴趣的人,我已经发布了一个要点,其中包含一些有用的部分类型,这些部分类型不允许过多的属性

https://gist.github.com/babakness/a1ca775f81097ffae04098a8cfdadc60

我不知道我是否真的理解用例,也无法重现你的结果。语法 function foo({a:2},{b:2}) 不是调用函数的方式;如果我将其更改为 foo({a:2},{b:2}) 我会得到 excess property checking complaining about the b property. It is always helpful to make sure you have provided a Minimum, Complete, and Verifiable Example 以便将回答者的精力集中在解决问题上而不是仅仅重现它。

综上所述,如果您真的需要 P 只包含来自 O 的键,您可以使用以下签名获得该行为(不确定边缘情况):

declare function foo<O, P extends { [K in keyof P]: K extends keyof O ? O[K] : never }>(
  obj: O,
  part: P
): P;

现在 P 被限制为一个类型,如果它们存在于 O 中,则其属性必须与 O 的属性匹配,否则它们必须是 never 类型,可以'发生与真正的价值。测试一下:

const x = { b: 2 }
foo({ a: 2 }, x); // error, types of property 'b' are incompatible
foo({ b: 2 }, x); // okay
foo({ a: 2 }, {}); // okay

看起来不错。希望有所帮助;祝你好运!