联合类型的所有可能的键

Xen*_*nya 8 typescript

我想获取一个联合类型的所有可用键。

interface Foo {
  foo: string;
}

interface Bar {
   bar: string;
}

type Batz = Foo | Bar;

type AvailableKeys = keyof Batz;
Run Code Online (Sandbox Code Playgroud)

我想得到的'foo' | 'bar'结果AvailableKeysnever(作为替代方案,我可以做的是keyof (Foo & Bar),产生确切所需类型的结果,但我想避免重复这些类型)。

我已经发现问题keyofunion类型应该在github上产生键的union。我知道答案,那keyof UnionType不应该产生所有可能的密钥。

所以我的问题是:是否有另一种方法来获取所有可能的键的列表(如果需要tsc的版本2.8是可以的)?

Tit*_*mir 9

这可以在打字稿2.8和更高版本中使用条件类型完成。条件类型遍历联合中的类型,对结果进行联合:

type Batz = Foo | Bar;

type KeysOfUnion<T> = T extends any ? keyof T: never;
// AvailableKeys will basically be keyof Foo | keyof Bar 
// so it will be  "foo" | "bar"
type AvailableKeys = KeysOfUnion<Batz>; 
Run Code Online (Sandbox Code Playgroud)

简单方法keyof Union不起作用的原因是keyof,在联合将仅是公共密钥的情况下,总是返回类型的可访问密钥。条件类型in KeysOfUnion实际上将采用联合的每个成员并获取其键,因此结果将是keyof应用于联合中每个成员的联合。

  • 为了更详细地解释这一点 - 这是由于上面@MártonSári链接的_distributive条件_而起作用的,其中联合类型上的条件子句会自动转换为条件联合。至关重要的是,语句“T extends T”始终为 TRUE,因此此类型会将 T 转换为条件的并集,所有条件都将遵循 true 分支。这基本上有点像黑客,因为我们根本没有做任何有条件的事情。 (4认同)
  • @dmwong2268 添加了更多解释,让我知道是否清楚 (2认同)
  • @TitianCernicova-Dragomir 您的解决方案有效,但您的解释似乎没有解释任何内容,只是重新说明了行为。我发现了关于 gitter 的讨论,其中您指出了解释它的正确位置,所以让我在这里添加它:https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional -类型 (2认同)