Skip to content

Instantly share code, notes, and snippets.

View pfftdammitchris's full-sized avatar
💭
Dreaming

Christopher Tran pfftdammitchris

💭
Dreaming
View GitHub Profile
@pfftdammitchris
pfftdammitchris / snippet-1.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-1.ts
interface UserState {
loading: boolean
data?: User
error?: Error
}
@pfftdammitchris
pfftdammitchris / snippet-2.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-2.ts
// Loading, but somehow also has data AND an error?
const weird: UserState = { loading: true, data: user, error: new Error() }
// Not loading, no data, no error — what does that even mean?
const empty: UserState = { loading: false }
@pfftdammitchris
pfftdammitchris / snippet-3.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-3.ts
type UserState =
| { status: 'loading' }
| { status: 'success'; data: User }
| { status: 'error'; error: Error }
@pfftdammitchris
pfftdammitchris / snippet-4.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-4.ts
function renderUser(state: UserState): string {
switch (state.status) {
case 'loading':
return 'Loading…'
case 'success':
// TypeScript knows `state.data` exists here
return `Welcome, ${state.data.name}`
case 'error':
// …and `state.error` exists here
return `Something went wrong: ${state.error.message}`
@pfftdammitchris
pfftdammitchris / snippet-5.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-5.ts
type UserState =
| { status: 'loading' }
| { status: 'success'; data: User }
| { status: 'error'; error: Error }
| { status: 'refreshing'; data: User } // new
@pfftdammitchris
pfftdammitchris / snippet-6.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-6.ts
function assertNever(value: never): never {
throw new Error(`Unhandled state: ${JSON.stringify(value)}`)
}
function renderUser(state: UserState): string {
switch (state.status) {
case 'loading':
return 'Loading…'
case 'success':
return `Welcome, ${state.data.name}`
@pfftdammitchris
pfftdammitchris / snippet-7.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-7.ts
type CheckoutState =
| { step: 'cart'; items: CartItem[] }
| { step: 'shipping'; items: CartItem[]; address: Address }
| { step: 'payment'; items: CartItem[]; address: Address; method: PayMethod }
| { step: 'confirmed'; orderId: string }
type CheckoutAction =
| { type: 'addAddress'; address: Address }
| { type: 'addPayment'; method: PayMethod }
| { type: 'confirm'; orderId: string }
@pfftdammitchris
pfftdammitchris / snippet-8.ts
Created July 9, 2026 18:18
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-8.ts
// Bad: `status` is `string`, so TypeScript can't narrow
interface Loose { status: string; data?: User }
// Good: literal union enables narrowing
type Tight = { status: 'idle' } | { status: 'ready'; data: User }
@pfftdammitchris
pfftdammitchris / snippet-1.ts
Created July 9, 2026 18:09
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-1.ts
interface UserState {
loading: boolean
data?: User
error?: Error
}
@pfftdammitchris
pfftdammitchris / snippet-2.ts
Created July 9, 2026 18:09
TypeScript Discriminated Unions: Make Illegal States Unrepresentable - snippet-2.ts
// Loading, but somehow also has data AND an error?
const weird: UserState = { loading: true, data: user, error: new Error() }
// Not loading, no data, no error — what does that even mean?
const empty: UserState = { loading: false }