javascript / intermediate
Snippet
Discriminated State Union Modeling with Reactive Signals
Using TypeScript discriminated unions with Angular signals enables strict type checking across asynchronous component states, preventing access to payload data when an error or idle state is active.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Injectable, signal, computed } from '@angular/core';type FetchStatus =| { state: 'idle' }| { state: 'loading' }| { state: 'success'; data: string[] }| { state: 'error'; message: string };@Injectable({ providedIn: 'root' })export class DataStateStore {private readonly statusSignal = signal<FetchStatus>({ state: 'idle' });readonly isLoaded = computed(() => this.statusSignal().state === 'success');readonly currentPayload = computed(() => {const s = this.statusSignal();return s.state === 'success' ? s.data : [];});setSuccess(payload: string[]): void {this.statusSignal.set({ state: 'success', data: payload });}}
angular
Breakdown
1
type FetchStatus = | { state: 'idle' } | ... | { state: 'success'; data: string[] };
Declares a discriminated union type using literal types as discriminator tags for state safety.
2
private readonly statusSignal = signal<FetchStatus>({ state: 'idle' });
Holds the reactive state container parameterized with the typed state union.
3
return s.state === 'success' ? s.data : [];
Narrows the union type via the state discriminator before safely accessing the data property.