TypeScript Trickiest Traps & Pro-Level Tips
🧠 TypeScript’s Trickiest Traps & Pro-Level Tips to Write Clean, Type-Safe Code 🚀
“JavaScript with superpowers” is how many describe TypeScript. But sometimes, those superpowers can be tricky to master! 🦸♂️
If you’re stepping into the world of TypeScript or already navigating its wild type jungles, this blog will save you hours of debugging and elevate your coding standards.
🛠️ First Things First: The Fundamentals You MUST Nail
Before we dive into the traps and tips, let’s talk about foundational practices that will save your sanity:
✅ 1. Always Enable strict
Mode
{
"compilerOptions": {
"strict": true
}
}
Enabling strict
unlocks the true power of TypeScript—null checks, type inferences, and preventing silent failures.
🔥 Pro Tip:
strictNullChecks
is a lifesaver for catching uninitialized values.
✅ 2. Use tsconfig
Like a Pro 🛠️
Set proper aliases, path resolutions, and include/exclude settings in tsconfig.json
.
"paths": {
"@components/*": ["src/components/*"]
}
🧩 Cleaner imports = cleaner mental model.
😵💫 TypeScript’s Trickiest Traps (And How to Escape Them)
Let’s talk about the sneaky stuff that even experienced devs fall into!
❗ 1. Confusing any
, unknown
, and never
Keyword | Meaning | When to Use |
---|---|---|
any |
Escape hatch 🕳️ | Avoid using—removes all type safety |
unknown |
Safe any |
Use when you don’t know the type but want type safety |
never |
Function never returns | Used in exhaustive checks or errors |
Wrong:
function risky(input: any) {
input.toUpperCase(); // 😱 runtime error if input is a number
}
Right:
function safe(input: unknown) {
if (typeof input === "string") {
input.toUpperCase(); // ✅
}
}
❗ 2. Misusing Union & Intersection Types 🤯
Wrong:
type User = { name: string } | { email: string }
const u: User = { name: "Lakhveer", email: "a@example.com" } // ❌ Invalid
Right:
type User = { name: string } & { email: string }
const u: User = { name: "Lakhveer", email: "a@example.com" } // ✅
📘 Tip: Use discriminated unions with
type
guards for better safety.
❗ 3. Optional Chaining vs Nullish Coalescing 😵
// ✅ Optional chaining
const userName = user?.name;
// ✅ Nullish coalescing
const status = user.status ?? 'guest';
⚠️ Don’t mix up with
||
which treats''
or0
as falsy.
❗ 4. Type Inference Isn’t Always Smart 🧠
Wrong:
const x = []; // inferred as never[]
x.push(5); // ❌ Error
Fix:
const x: number[] = [];
x.push(5); // ✅
✅ Always give explicit types to empty arrays or variables initialized later.
❗ 5. Forgetting to Narrow Down null | undefined
🧼
Fix: Use optional chaining and null checks:
if (user?.name) {
console.log(user.name.toUpperCase()); // Safe ✅
}
✅ Suggestions to Write TypeScript Code Like a Pro
🧩 1. Use as const
for Immutable Data
const roles = ['admin', 'user'] as const;
type Role = typeof roles[number]; // 'admin' | 'user'
🧩 2. Leverage Utility Types
TypeScript has powerful built-in types:
Partial<T>
Pick<T, K>
Omit<T, K>
Readonly<T>
Example:
type User = { name: string; email: string }
type EditableUser = Partial<User>
🧩 3. Use Type Guards 🚨
function isString(value: unknown): value is string {
return typeof value === 'string';
}
✨ Custom type guards = custom safety net!
🧩 4. Prefer interface
for Objects, type
for Everything Else
interface
is extendable and ideal for object shapes.type
is better for unions, tuples, primitives.
🧩 5. Master Enums and Literal Types ⚙️
type Status = 'pending' | 'completed' | 'failed';
function handle(status: Status) {
switch (status) {
case 'pending': break;
case 'completed': break;
case 'failed': break;
}
}
Use literal types instead of Enums when possible for better tree-shaking and clarity.
🧩 6. Use Zod / Yup for Runtime Type Safety 🛡️
TypeScript only exists at compile time. If you’re validating data from APIs, use runtime validators like:
import { z } from 'zod';
const UserSchema = z.object({
name: z.string(),
age: z.number(),
});
✅ Combine static and runtime safety for ultimate robustness.
🎁 Bonus Tips
✅ Use ts-node-dev
for hot reload during dev
✅ Use VSCode’s TypeScript plugin for inline type hints
✅ Write JSDoc
style comments above complex types
✅ Avoid deep nesting of types—break them into reusable ones
✅ Prefer composition over inheritance with types
🔚 Wrapping Up
TypeScript makes your JavaScript smarter—but only if you use it right. Avoiding these traps and following the above suggestions will help you write clean, safe, and scalable code 🧼🚀
💡 “You don’t need to type everything—but you should type the right things.” – Every TypeScript Master Ever
📣 Share & Save!
If you found this useful, don’t forget to share it with your TypeScript squad. Happy typing! 💻✨
© Lakhveer Singh Rajput - Blogs. All Rights Reserved.