TypeScript 类型级编程:检查对象是否至少有两个字段

问题描述 投票:0回答:1

我正在尝试使用一个库进行通用编程,该库要求输入对象至少有两个字段(无论它们的名称是什么)。我想创建一个实用程序类型来测试这一点。

type A = ObjectWithAtLeastTwoFields<{ a: 0, b: 1 }> // { a: 0, b: 1 }
type B = ObjectWithAtLeastTwoFields<{ a: 0 }> // never
type C = ObjectWithAtLeastTwoFields<{}> // never
typescript type-level-computation
1个回答
0
投票

本质上我们要检查

keyof X
的长度是否至少为 2。现在,
keyof X
将为您提供所有可能字段的并集,例如
A | B | ...
。您无法直接迭代联合值,但是有一种可怕的方法可以将联合转换为元组,此时您可以获取其长度。


这里是

jcalz
的相关回答:如何将union类型转换为tuple类型

附带免责声明:

免责声明:不要这样做!如果有人告诉您使用他们在这个答案中找到的代码来做任何事情,除了证明为什么这是一个坏主意,请跑开!!

但是让我们真正理解为什么这是一个坏主意。也许这里更受限制的问题使得这个方法可以?

让我们回顾一下

jcalz
引用的原因:

  1. 您不能依赖联合类型的排序。

    这与仅仅计算成员数量无关,到目前为止还可以。

  2. 您可能对编译器所认为的联合以及它何时折叠或展开不满意。

    这实际上确实影响我们的用例,因为有人可能会在没有静态已知字段的类型上使用

    ObjectWithAtLeastTwoFields
    。例如,
    const x: Record<string, number> = {a: 1, b: 2}
    至少有两个字段,但是
    keyof (typeof x) = string
    所以我们的代码只能找到一个“字段”并失败。

出于同样的原因,没有其他方法可以可靠地使用通用对象。如果所有字段名称的集合不是静态可用的或者在某些时候丢失,例如将文字与类型统一起来, 没有足够的信息让该谓词发挥作用。


如果您了解所有风险并且无论如何都想这样做,那么这里是 打字稿游乐场中的一些代码。

© www.soinside.com 2019 - 2024. All rights reserved.