如何要求参数成为严格扩展局部的泛型

时间:2018-11-24 20:01:10

标签: typescript generics typescript-typings typescript-generics

我正在尝试实现直观的结果,说明某些通用P是O的部分。

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

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

// 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

1 个答案:

答案 0 :(得分:1)

我不知道我是否真的了解用例,也无法复制您的结果。语法function foo({a:2},{b:2})并不是调用函数的方式;如果将其更改为foo({a:2},{b:2}),则会收到excess property checking抱怨b属性。确保您提供了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

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

相关问题