Typescript接口类型值转换为联合类型

18

在 TypeScript 中,是否有可能通过一个接口获取所有类型值的联合类型?

例如,当给出一个接口:

interface A {
  a: string;
  b: () => void;
  c: number;
  d: string;
  e: 'something';
}

结果应该是

type B = string | () => void | number | 'something';

我不知道该如何解决这个问题,甚至不确定是否有可能解决。

2个回答

34

您可以使用keyof,例如:

 type B = A[keyof A] // will be string | number | (() => void)

由于编译器不区分类型stringsomething,因为两者都是字符串,所以类型something不会出现在type B中。


是的,这个可以工作!但我真的想知道为什么。我从来没有在任何地方读到过,你可以把一个联合类型(keyof A)放到接口的键括号中。你知道吗,在官方文档中是否提到了这一点? - Peter Lehnhardt
1
@PeterLehnhardt 这里有两件事情。首先,keyof返回A的键。其次,A['a']将返回键a的类型。因此,它映射键以获取它们的类型。 - Murat Karagöz
2
是的,你说的两件事情我都明白了。唯一让我困惑的是,身份证 A["a" | "b"] = A["a"] | A["b"](基本上是你答案的基本形式)是正确的,但在 TypeScript 文档中似乎没有提到过。我认为这很奇怪,语言中存在一个未被明确说明的规则!如果还有其他规则,我该怎么知道呢?所以我的问题实际上是:你是从哪里得知这个规则的? - Peter Lehnhardt

1

您需要一些高级的TypeScript。

以下示例中,keyof A 可以完全与 string | () => void | number | 'something'; 互换使用。区别在于,如果您向 A 添加另一个属性,比如 myfunc: string,则 keyof A 将自动更新为 string | () => void | number | something |myfunc。并且您可以将 keyof 用于泛型上下文,例如 pluck,其中您不可能预先知道属性名称。这意味着编译器将检查您是否将正确的属性名称集传递给了 pluck:

pluck(A, ['number ', 'unknown']); // error, 'unknown' is not in string | () => void | number | 'something';

它可以被

let B :keyof A;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接