1

我试图达到说明一些通用 P 是 O 的一部分的直观结果。

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

但是,这允许键不是 O 的 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})

但是返回类型不能是泛型 P。

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

- 更新

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

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

4

1 回答 1

2

我不知道我是否真的了解用例,也无法重现您的结果。语法function foo({a:2},{b:2})不是你调用函数的方式;如果我将其更改为foo({a:2},{b:2})我得到过多的财产检查抱怨b财产。确保您提供了一个最小的、完整的和可验证的示例总是很有帮助的,以便将回答者的精力集中在解决问题上,而不是仅仅复制它。

话虽如此,如果您真的P只需要其中的密钥O,则可以使用以下签名获得该行为(不确定边缘情况):

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

NowP仅限于其属性必须匹配的类型,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

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

于 2018-11-24T20:34:30.620 回答