【问题标题】:How to require parameter to be a generic strictly extending a partial如何要求参数是严格扩展部分的泛型
【发布时间】:2019-04-26 23:07:47
【问题描述】:

我试图达到说明一些通用 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

【问题讨论】:

    标签: typescript generics typescript-typings typescript-generics


    【解决方案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
    

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

    【讨论】:

    • function foo({a:2},{b:2}) 是一个错字,意思是foo({a:2},{b:2})
    • 有趣的是看到 P 扩展了一个由它自己组成的计算对象。
    • 奇怪,在我提供的第一个示例中,我没有收到错误。对我来说这是“可验证的”;第二个示例确实按预期工作我根本没有得到通用 P。无论如何,感谢您的帮助!
    • 我认为可验证性(可验证性?)只是您可以使用 separate environment 测试的东西,否则您将冒着“验证”不可重现的风险。
    • 啊,我明白了,我确实有问题,你说得对,我真的的意思是foo({ a: 2 },{a:100, b: 2})
    猜你喜欢
    • 2020-08-30
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多