打字稿:查找类型组

Typescript: Find Type Group

我有几种:

type A = A1 | A2 | A3;

type B = B1 | B2 | B3;

type AnyType = A | B;

所有类型(A1A2A3B1B2B3)都是类.

还有一个函数接收 AnyType 调用 action:

function myReducerFunction(action: AnyType) {
  // Does action belong to A or B here?
}

我正在使用 NgRx 构建一个 reducer,我想将 switch 语句拆分为更易于管理的块。因此,根据 action 是 A 还是 B 中的任何一个,我会 return 任何一个“subreducer” returns,而不是在一个大的中处理它函数。

那么,我怎么知道 something 是函数中的 A 还是 B

使用接口而不是类型是否更有意义?如果可以,是否可以通过类型完成,如何完成?

如果您使用没有 class 信息的纯“形状”,每个形状通常会有一个共同成员,例如 kind,您可以将其用作标识符。

  enum Kind {
      A1=1,A2,A3,B1,B2,B3
  }

  type A1 = {
      kind: typeof Kind.A1
      foo:number
  }
  type A2 = {
      kind: typeof Kind.A2
      bar:number
  }

function myReducerFunction(action: AnyType) {
  switch (action.kind){
      case Kind.A1: console.log(action.foo); break;
      case Kind.A2: console.log(action.bar); break;
  }   
}

当然既然你已经写了classes你也可以用instanceof来区分。但要注意 c instanceof C 也匹配任何扩展 C.

的 class

Typescript 的类型在运行时不存在,因此您需要使用纯 JS 来决定您的操作是什么类型。

因为 A1-3B1-3 是 类,这可以很容易地用 instanceof 完成。 与 type predicate 相结合,您可以构建如下内容:

function isTypeA(val: AnyType): val is A {
  return [A1, A2, A3].some(clazz => val instanceof clazz);

}

function isTypeB(val: AnyType): val is B {
  return [B1, B2, B3].some(clazz => val instanceof clazz);
}

function myReducerFunction(action: AnyType) {
  if (isTypeA(action)) {
    // TS will now assume action is of type A.
  } else {
    // TS will now assume action is of type B.
    // You might not even need `isTypeB` since TS will be smart enough to realize 
    // `action` can only be type B here.
  }
}

使用类型谓词,您将能够访问 A1-3B1-3 独有的属性,而不会引起 Typescript 的抱怨!