TypeScript中|运算符用于类联合类型的原因咨询
| Operator as a Union Type in TypeScript (NgRx Example) Great question! I totally get why this would throw you off at first—when you search for | in TypeScript, most initial results focus on its role as the bitwise OR operator (which operates on numeric values at runtime). But in the NgRx code snippet you shared, that | is serving an entirely different purpose: it's defining a union type, one of TypeScript's core type system features.
Let's break this down step by step:
What is a Union Type?
A union type (written with TypeA | TypeB | TypeC) tells TypeScript that a value can be any one of the listed types. In your example:
export type CounterActionsUnion = Increment | Decrement | Reset;
This means any variable or parameter typed as CounterActionsUnion can be an instance of the Increment class, the Decrement class, or the Reset class. It's TypeScript's way of saying "this value could be one of these things, and I need to check which one it is to use it correctly."
Why Use This in NgRx?
NgRx actions are classes that implement the Action interface, each with a unique type property to identify what kind of action it is. By creating a union type of all your counter actions:
- TypeScript can perform type narrowing: When you check an action's
typeproperty (e.g.,if (action.type === CounterActionTypes.RESET)), TypeScript automatically knows that the action is aResetinstance, so it will let you access thepayloadproperty without errors. - Your reducer functions become type-safe: You won't accidentally try to access a
payloadon anIncrementaction (which doesn't have one), because TypeScript will flag that as a compile-time error.
Key Difference: Bitwise OR vs. Union Type
It's crucial to distinguish these two uses of |:
- Bitwise OR (
a | b): A runtime operator that manipulates numeric values (e.g.,3 | 5evaluates to7). This is what you found in your initial Google search. - Union Type (
TypeA | TypeB): A compile-time type annotation that only exists in TypeScript's type system. It gets erased when your code is compiled to JavaScript—there's no corresponding runtime behavior.
Example in Practice
Here's how this union type works in a typical NgRx reducer:
function counterReducer(state = 0, action: CounterActionsUnion): number { switch (action.type) { case CounterActionTypes.INCREMENT: // TypeScript knows action is Increment here—no payload return state + 1; case CounterActionTypes.DECREMENT: // TypeScript knows action is Decrement here—no payload return state - 1; case CounterActionTypes.RESET: // TypeScript knows action is Reset here—so payload is available return action.payload; default: return state; } }
Without the union type, TypeScript would only know action is an Action (which only has a type property), and you'd have to manually assert the type to access payload—which defeats the purpose of type safety.
内容的提问来源于stack exchange,提问作者Code Apprentice

