Tools: TypeScript Tricks I Actually Use Day to Day (2026)

Tools: TypeScript Tricks I Actually Use Day to Day (2026)

I've been writing TypeScript for a few years now across React Native, Node.js, and a bunch of different product types. And there's a gap between what the docs teach you and what you actually end up reaching for every day. Here are the patterns I keep coming back to. Discriminated unions for state management This one changed how I model data. Instead of a bunch of optional fields that may or may not exist, you define each state explicitly. Now TypeScript knows exactly what's available in each case. No more data might be undefined checks scattered everywhere. satisfies instead of direct type annotation This one's newer but I use it a lot now. The difference is subtle but useful. With satisfies, you get type checking without losing the literal types. If you annotate directly with Record, you lose the specific values. Small thing, big difference when you're chaining or inferring from it. Utility types you actually need Everyone knows Partial and Required. These are the ones I reach for more often: That last one is something I use constantly for update/patch endpoints. Template literal types for string contracts Useful when you're dealing with event names, routes, or anything string-based that needs structure. Catches a whole class of bugs at compile time instead of runtime. infer for extracting types from generics Looks scary at first but once it clicks, you use it everywhere. I use UnpackPromise constantly when working with async functions and I need the resolved type without awaiting. Const assertions for config objects Stop widening your types when you don't need to. Clean, no manual duplication, and the type stays in sync automatically. None of these are exotic. They're just the things that come up over and over when you're building real products. The more you use them the more the TypeScript compiler starts feeling like a teammate rather than something you're fighting against. That's the shift worth chasing. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to ? It will become hidden in your post, but will still be visible via the comment's permalink. as well , this person and/or

Code Block

Copy

type RequestState = | { status: "idle" } | { status: "loading" } | { status: "success"; data: User } | { status: "error"; message: string }; CODE_BLOCK: type RequestState = | { status: "idle" } | { status: "loading" } | { status: "success"; data: User } | { status: "error"; message: string }; CODE_BLOCK: type RequestState = | { status: "idle" } | { status: "loading" } | { status: "success"; data: User } | { status: "error"; message: string }; CODE_BLOCK: const config = { theme: "dark", language: "en", } satisfies Record<string, string>; CODE_BLOCK: const config = { theme: "dark", language: "en", } satisfies Record<string, string>; CODE_BLOCK: const config = { theme: "dark", language: "en", } satisfies Record<string, string>; COMMAND_BLOCK: // Pick only what you need type Preview = Pick<Article, "title" | "slug" | "createdAt">; // Exclude what you don't type PublicUser = Omit<User, "password" | "token">; // Make specific fields optional type UpdateInput = Partial<Pick<User, "name" | "bio">> & Pick<User, "id">; COMMAND_BLOCK: // Pick only what you need type Preview = Pick<Article, "title" | "slug" | "createdAt">; // Exclude what you don't type PublicUser = Omit<User, "password" | "token">; // Make specific fields optional type UpdateInput = Partial<Pick<User, "name" | "bio">> & Pick<User, "id">; COMMAND_BLOCK: // Pick only what you need type Preview = Pick<Article, "title" | "slug" | "createdAt">; // Exclude what you don't type PublicUser = Omit<User, "password" | "token">; // Make specific fields optional type UpdateInput = Partial<Pick<User, "name" | "bio">> & Pick<User, "id">; CODE_BLOCK: type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"; type Endpoint= `/${string}`; type Route = `${HttpMethod} ${Endpoint}`; const route: Route = "GET /users"; // valid const bad: Route = "FETCH /users"; // error CODE_BLOCK: type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"; type Endpoint= `/${string}`; type Route = `${HttpMethod} ${Endpoint}`; const route: Route = "GET /users"; // valid const bad: Route = "FETCH /users"; // error CODE_BLOCK: type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"; type Endpoint= `/${string}`; type Route = `${HttpMethod} ${Endpoint}`; const route: Route = "GET /users"; // valid const bad: Route = "FETCH /users"; // error COMMAND_BLOCK: type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never; type UnpackPromise<T> = T extends Promise<infer U> ? U : T; COMMAND_BLOCK: type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never; type UnpackPromise<T> = T extends Promise<infer U> ? U : T; COMMAND_BLOCK: type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never; type UnpackPromise<T> = T extends Promise<infer U> ? U : T; CODE_BLOCK: const ROLES = ["admin", "user", "guest"] as const; type Role = typeof ROLES[number]; // "admin" | "user" | "guest" CODE_BLOCK: const ROLES = ["admin", "user", "guest"] as const; type Role = typeof ROLES[number]; // "admin" | "user" | "guest" CODE_BLOCK: const ROLES = ["admin", "user", "guest"] as const; type Role = typeof ROLES[number]; // "admin" | "user" | "guest"