我正在尝试实现直观的结果,说明某些通用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
答案 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
看起来不错。希望能有所帮助;祝你好运!