I have a a few types:
type A = A1 | A2 | A3;
type B = B1 | B2 | B3;
type AnyType = A | B;
All the types (A1
, A2
, A3
, B1
, B2
, B3
) are classes.
There's also a function which receives an AnyType
called action
:
function myReducerFunction(action: AnyType) {
// Does action belong to A or B here?
}
I'm building a reducer with NgRx and I'd like to split the switch statement into more manageable blocks. Hence, depending on whether action is any of A
or any of B
I'd return whatever a "subreducer" returns, instead of handling it all in one big function.
So, how can I know if something
is an A
or a B
inside that function?
Would it make more sense to use interfaces instead of types? If it would, could it be done with types anyway, and how?
Typescript's types don't exist during runtime, so you'll need to use plain JS to decide what type your action is.
Since A1-3
and B1-3
are classes, this can easily be done with instanceof
.
Combined with a type predicate you can build something like:
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.
}
}
With type predicates, you'll be able to access properties exclusive to A1-3
or B1-3
without Typescript complaining!