Created
March 14, 2026 15:13
-
-
Save mohashari/cf0ac9572635ff473fa0f7320a445179 to your computer and use it in GitHub Desktop.
Code snippets — Typescript For Backend Engineers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Type guard: narrows type based on runtime check | |
| function isApiError(error: unknown): error is ApiError { | |
| return ( | |
| typeof error === 'object' && | |
| error !== null && | |
| 'statusCode' in error && | |
| 'message' in error | |
| ); | |
| } | |
| async function fetchUser(id: string) { | |
| try { | |
| return await api.getUser(id); | |
| } catch (error: unknown) { | |
| if (isApiError(error)) { | |
| // TypeScript knows error.statusCode and error.message exist | |
| if (error.statusCode === 404) { | |
| return null; | |
| } | |
| throw new Error(`API error ${error.statusCode}: ${error.message}`); | |
| } | |
| throw error; // Re-throw unknown errors | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Partial — all fields optional | |
| type UpdateUserRequest = Partial<User>; | |
| // Required — all fields required (opposite of Partial) | |
| type StrictUser = Required<User>; | |
| // Pick — select specific fields | |
| type UserSummary = Pick<User, 'id' | 'name' | 'email'>; | |
| // Omit — exclude specific fields | |
| type CreateUserRequest = Omit<User, 'id' | 'createdAt'>; | |
| // Record — dictionary type | |
| type UsersByID = Record<string, User>; | |
| // Readonly — prevent mutation | |
| type ImmutableConfig = Readonly<Config>; | |
| // ReturnType — extract function return type | |
| async function getUser(id: string): Promise<User> { ... } | |
| type UserPromise = ReturnType<typeof getUser>; // Promise<User> | |
| // Parameters — extract function parameter types | |
| type GetUserParams = Parameters<typeof getUser>; // [string] | |
| // Extract and Exclude — filter union types | |
| type StringOrNumber = string | number | boolean; | |
| type OnlyStrings = Extract<StringOrNumber, string>; // string | |
| type NoStrings = Exclude<StringOrNumber, string>; // number | boolean |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Basic generic | |
| function first<T>(arr: T[]): T | undefined { | |
| return arr[0]; | |
| } | |
| // Constrained generic — T must have an id field | |
| function findById<T extends { id: string }>(items: T[], id: string): T | undefined { | |
| return items.find(item => item.id === id); | |
| } | |
| // Multiple constraints | |
| function merge<T extends object, U extends object>(target: T, source: U): T & U { | |
| return { ...target, ...source }; | |
| } | |
| // Conditional types | |
| type NonNullable<T> = T extends null | undefined ? never : T; | |
| type Awaited<T> = T extends Promise<infer U> ? U : T; | |
| // Infer keyword — extract types from other types | |
| type UnpackPromise<T> = T extends Promise<infer Inner> ? Inner : T; | |
| type UnpackArray<T> = T extends (infer Element)[] ? Element : T; | |
| // Usage | |
| type UserData = UnpackPromise<ReturnType<typeof fetchUser>>; // User | |
| type OrderItem = UnpackArray<Order['items']>; // Item |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type Result<T, E = Error> = | |
| | { success: true; data: T } | |
| | { success: false; error: E }; | |
| async function getUser(id: string): Promise<Result<User, 'NOT_FOUND' | 'DB_ERROR'>> { | |
| try { | |
| const user = await db.users.findById(id); | |
| if (!user) { | |
| return { success: false, error: 'NOT_FOUND' }; | |
| } | |
| return { success: true, data: user }; | |
| } catch { | |
| return { success: false, error: 'DB_ERROR' }; | |
| } | |
| } | |
| // Caller handles both cases explicitly | |
| const result = await getUser('42'); | |
| if (!result.success) { | |
| switch (result.error) { | |
| case 'NOT_FOUND': | |
| return res.status(404).json({ error: 'User not found' }); | |
| case 'DB_ERROR': | |
| return res.status(500).json({ error: 'Database error' }); | |
| } | |
| } | |
| // TypeScript knows result.data is User here | |
| const user = result.data; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { z } from 'zod'; | |
| const CreateOrderSchema = z.object({ | |
| userId: z.string().uuid(), | |
| items: z.array(z.object({ | |
| productId: z.string().uuid(), | |
| quantity: z.number().int().positive().max(100), | |
| })).min(1), | |
| shippingAddress: z.object({ | |
| street: z.string().min(1), | |
| city: z.string().min(1), | |
| country: z.string().length(2), // ISO country code | |
| }), | |
| }); | |
| // Infer TypeScript type from schema (single source of truth!) | |
| type CreateOrderRequest = z.infer<typeof CreateOrderSchema>; | |
| // Validate at API boundary | |
| app.post('/orders', async (req, res) => { | |
| const result = CreateOrderSchema.safeParse(req.body); | |
| if (!result.success) { | |
| return res.status(422).json({ | |
| error: 'Validation failed', | |
| details: result.error.flatten(), | |
| }); | |
| } | |
| // result.data is typed as CreateOrderRequest | |
| const order = await createOrder(result.data); | |
| res.status(201).json(order); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Type-safe event names | |
| type EventName = `${string}Created` | `${string}Updated` | `${string}Deleted`; | |
| // Type-safe HTTP methods | |
| type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; | |
| type ApiRoute = `${HttpMethod} /api/${string}`; | |
| // Type-safe environment variable keys | |
| type EnvKey = `DATABASE_${string}` | `REDIS_${string}` | `JWT_${string}`; | |
| function getEnv(key: EnvKey): string { | |
| const value = process.env[key]; | |
| if (!value) throw new Error(`Missing env var: ${key}`); | |
| return value; | |
| } | |
| getEnv('DATABASE_URL'); // OK | |
| getEnv('DB_URL'); // TypeScript error! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Instead of nullable fields (confusing) | |
| interface Order { | |
| id: string; | |
| status: string; | |
| paidAt?: Date; // Only when paid | |
| trackingCode?: string; // Only when shipped | |
| cancelReason?: string; // Only when cancelled | |
| } | |
| // Use discriminated unions (explicit) | |
| type Order = | |
| | { status: 'pending'; id: string; createdAt: Date } | |
| | { status: 'paid'; id: string; createdAt: Date; paidAt: Date; amount: number } | |
| | { status: 'shipped'; id: string; createdAt: Date; paidAt: Date; trackingCode: string } | |
| | { status: 'cancelled'; id: string; createdAt: Date; cancelReason: string }; | |
| function processOrder(order: Order) { | |
| switch (order.status) { | |
| case 'paid': | |
| // TypeScript knows paidAt and amount exist here | |
| console.log(`Paid ${order.amount} at ${order.paidAt}`); | |
| break; | |
| case 'shipped': | |
| // TypeScript knows trackingCode exists here | |
| console.log(`Tracking: ${order.trackingCode}`); | |
| break; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment