我正在尝试使用一个库进行通用编程,该库要求输入对象至少有两个字段(无论它们的名称是什么)。我想创建一个实用程序类型来测试这一点。
type A = ObjectWithAtLeastTwoFields<{ a: 0, b: 1 }> // { a: 0, b: 1 }
type B = ObjectWithAtLeastTwoFields<{ a: 0 }> // never
type C = ObjectWithAtLeastTwoFields<{}> // never
本质上我们要检查
keyof X
的长度是否至少为 2。现在,keyof X
将为您提供所有可能字段的并集,例如A | B | ...
。您无法直接迭代联合值,但是有一种可怕的方法可以将联合转换为元组,此时您可以获取其长度。
这里是
jcalz
的相关回答:如何将union类型转换为tuple类型
附带免责声明:
免责声明:不要这样做!如果有人告诉您使用他们在这个答案中找到的代码来做任何事情,除了证明为什么这是一个坏主意,请跑开!!
但是让我们真正理解为什么这是一个坏主意。也许这里更受限制的问题使得这个方法可以?
让我们回顾一下
jcalz
引用的原因:
您不能依赖联合类型的排序。
这与仅仅计算成员数量无关,到目前为止还可以。
您可能对编译器所认为的联合以及它何时折叠或展开不满意。
这实际上确实影响我们的用例,因为有人可能会在没有静态已知字段的类型上使用
ObjectWithAtLeastTwoFields
。例如, const x: Record<string, number> = {a: 1, b: 2}
至少有两个字段,但是 keyof (typeof x) = string
所以我们的代码只能找到一个“字段”并失败。
出于同样的原因,没有其他方法可以可靠地使用通用对象。如果所有字段名称的集合不是静态可用的或者在某些时候丢失,例如将文字与类型统一起来, 没有足够的信息让该谓词发挥作用。
如果您了解所有风险并且无论如何都想这样做,那么这里是 打字稿游乐场中的一些代码。