A common TypeScript anti-pattern I keep seeing. When working with nested arrays, many developers lean on optional chaining everywhere, especially inside loops. It feels safe. It feels concise. But it quietly introduces unnecessary branching and noisy logic. --- 🛡️ The “defensive everywhere” approach ``` function getActiveEmails(data?: ApiResponse) { return data?.users ?.filter(u => u?.isActive) ?.map(u => u?.profile?.email ?? "no-email") ?? []; } ``` What’s happening here? - "data?.users" → branch - "u?.isActive" → branch per iteration - "u?.profile?.email" → multiple branches per iteration - "?? []" → fallback branch You’ve now created a combinatorial explosion of paths inside what should be a simple transformation. Your tests? They now need to cover: - missing "data" - missing "users" - partially invalid users - missing profiles - missing emails All implicitly baked into one chain. --- ✅ Early return & controlled assumptions ``` function getActiveEmails(data?: ApiResponse) { if (!data?.users) return []; return data.users .filter(user => user.isActive) .map(user => user.profile.email); } ``` Key differences: - The guard ("if") still uses optional chaining, but only once, at the boundary - Inside the loop, we treat data as valid by contract - No defensive noise inside "filter"/"map" - The “happy path” is clean and linear --- Why? Optional chaining inside iteration is especially costly: - It introduces branches per element - It hides data contract issues - It bloats test cases unnecessarily - It makes bugs harder to spot (everything just becomes “undefined”) --- So, - Use optional chaining at the edges of your system - Use early returns to establish guarantees - Keep your core logic branch light and explicit --- Optional chaining isn’t the problem. Unstructured defensiveness is. #TypeScript #JavaScript #CleanCode #CodeQuality #Refactoring #BestPractices #DeveloperTips
TypeScript Anti-Pattern: Optional Chaining in Loops
More Relevant Posts
-
5 TypeScript patterns I copy into every new project. Steal these. 1. Strict null checks everywhere tsconfig: "strictNullChecks": true Forces you to handle undefined. Catches bugs before runtime. Non-negotiable. 2. Utility types for API responses type ApiResponse<T> = { data: T; error: string | null; loading: boolean; } Consistent shape for every API call. Components always know what to expect. 3. Discriminated unions for state type State = | { status: 'loading' } | { status: 'success'; data: User } | { status: 'error'; error: string } No more "loading && data && !error" checks. TypeScript narrows the type automatically. 4. Branded types for IDs type UserId = string & { __brand: 'UserId' } type PostId = string & { __brand: 'PostId' } Prevents accidentally passing a PostId where UserId is expected. Catches bugs at compile time. 5. Const assertions for constants const ROLES = ['admin', 'user', 'guest'] as const; type Role = typeof ROLES[number]; Type is 'admin' | 'user' | 'guest', not string. No magic strings. These patterns add maybe 5 minutes of setup. They've saved me hours of debugging. #TypeScript #DeveloperTools #Frontend
To view or add a comment, sign in
-
NestJS without DTOs is a bug waiting to happen. Here's the pattern I use instead. I took over a NestJS codebase last year. Controllers were receiving raw request bodies. No validation. No typing. `req.body` passed directly into database calls. One bad payload and you're looking at a data corruption bug that takes three days to trace. The fix is DTOs — Data Transfer Objects — combined with class-validator. But most tutorials show the basic version. Here's how I actually use them: // Basic (what most tutorials show) @Post() create(@Body() body: any) { // body is any return this.service.create(body) } // What I do on every project import { IsEmail, IsString, MinLength, IsEnum } from 'class-validator' import { Transform } from 'class-transformer' export class CreateUserDto { @IsEmail() @Transform(({ value }) => value.toLowerCase().trim()) email: string @IsString() @MinLength(8) password: string @IsEnum(['admin', 'user', 'guest']) role: 'admin' | 'user' | 'guest' } @Post() create(@Body() dto: CreateUserDto) { // validated and transformed return this.service.create(dto) } With ValidationPipe enabled globally, NestJS now: → Rejects any request that doesn't match the DTO shape → Returns a proper 400 with the exact field that failed → Transforms the data before it reaches your service → Strips any extra fields the client shouldn't send 3 things I never skip on NestJS DTOs: 1. @Transform for sanitisation (trim whitespace, lowercase emails) 2. @Exclude on response DTOs so passwords never leak 3. Separate request and response DTOs — what comes in is not what goes out What validation pattern do you use in your Node.js/NestJS APIs? #NestJS #NodeJS #TypeScript #BackendDevelopment #WebDevelopment
To view or add a comment, sign in
-
-
📘 𝐉𝐚𝐯𝐚𝐒𝐜𝐫𝐢𝐩𝐭 𝐈𝐧𝐭𝐞𝐫𝐯𝐢𝐞𝐰 𝐌𝐨𝐝𝐮𝐥𝐞 (𝐁𝐚𝐬𝐢𝐜) 𝐒𝐞𝐜𝐭𝐢𝐨𝐧 2: 𝐕𝐚𝐫𝐢𝐚𝐛𝐥𝐞𝐬 1.What is a variable? 2.Why do we use a variable? 3.How to declare a variable? 4.Tell me about variable declaration rules? 5.How many types of variables do you know? 6.When do we use var? 7.When do we use let? 8.When do we use const? 9.How to create an undefined variable? 10.What is an undefined variable? 11.What is undefined? 12.What is NaN? 13.What is null? 14.What is concatenation? 15.What is Infinity? 16.How to assign data to a variable / How to assign a variable data? 17.Variable is primitive or non-primitive? 🎯 𝐈𝐧𝐭𝐞𝐫𝐯𝐢𝐞𝐰 𝐐𝐮𝐞𝐬𝐭𝐢𝐨𝐧𝐬 (𝐄𝐱𝐭𝐫𝐚) 1.Difference between var, let, and const? 2.What is variable hoisting? 3.Why can var be accessed before declaring it? 4.What is temporal dead zone (TDZ)? 5.Can we reassign const variable? 6.Why shouldn't modern JavaScript use var? 𝐒𝐞𝐜𝐭𝐢𝐨𝐧 3: 𝐉𝐚𝐯𝐚𝐒𝐜𝐫𝐢𝐩𝐭 𝐃𝐚𝐭𝐚 𝐓𝐲𝐩𝐞𝐬 & 𝐊𝐞𝐲𝐰𝐨𝐫𝐝𝐬 1.JavaScript data types? 2.What is a reserved keyword? 3.What is a special keyword? 4.How can check type data type? 5.JavaScript variables is case-sensitive? 6.JavaScript variable naming conventions? 7.How to convert string ("20") to number (20)? 8.JavaScript built-in functions? 🎯 𝐈𝐧𝐭𝐞𝐫𝐯𝐢𝐞𝐰 𝐐𝐮𝐞𝐬𝐭𝐢𝐨𝐧𝐬 (𝐄𝐱𝐭𝐫𝐚) 1.Difference between primitive and reference types? 2.What is type coercion? 3.Difference between null and undefined? 4.What is typeof null / What is the output of typeof null and why? (Important trick question) 5.What is the difference in memory management between primitive and reference type data? #DotNet #AspNetCore #MVC #FullStack #SoftwareEngineering #ProgrammingTips #DeveloperLife #LearnToCode #JavaScript #JS #JavaScriptTips #JSLearning #FrontendDevelopment #WebDevelopment #CodingTips #CodeManagement #DevTools
To view or add a comment, sign in
-
-
Most React bugs aren't logic errors. They're state shape errors. ⚠️ The type allowed it. And nobody caught it until production. 𝗛𝗲𝗿𝗲'𝘀 𝘄𝗵𝗮𝘁 𝗺𝗼𝘀𝘁 𝗧𝘆𝗽𝗲𝗦𝗰𝗿𝗶𝗽𝘁 𝘀𝘁𝗮𝘁𝗲 𝗹𝗼𝗼𝗸𝘀 𝗹𝗶𝗸𝗲: interface RequestState { isLoading: boolean; data?: User; error?: string; } This type allows impossible states: ● isLoading: true AND data: User at the same time ● error: "failed" AND data: User at the same time ● isLoading: false with no data and no error — what just happened? setState({ isLoading: false, data: undefined, error: undefined }); UI shows nothing. No loading. No error. Just a blank screen. Your UI is now guessing which state is real. 𝗗𝗶𝘀𝗰𝗿𝗶𝗺𝗶𝗻𝗮𝘁𝗲𝗱 𝘂𝗻𝗶𝗼𝗻𝘀 𝗲𝗹𝗶𝗺𝗶𝗻𝗮𝘁𝗲 𝘁𝗵𝗲 𝗴𝘂𝗲𝘀𝘀𝗶𝗻𝗴: type RequestState = | { status: 'idle' } | { status: 'loading' } | { status: 'success'; data: User } | { status: 'error'; error: string } Now impossible states are actually impossible. data only exists on success. error only exists on error. TypeScript enforces it — not your runtime checks. 𝗨𝘀𝗶𝗻𝗴 𝗶𝘁 𝗶𝗻 𝗮 𝗰𝗼𝗺𝗽𝗼𝗻𝗲𝗻𝘁: switch (state.status) { case 'loading': return <Spinner />; case 'error': return <Error message={state.error} />; case 'success': return <Dashboard data={state.data} />; default: return null; } No optional chaining. No data?.user?.name. No undefined checks. The compiler already knows what exists at each branch. ⚠️ Boolean flags scale poorly. State machines don't. 🎯 𝗧𝗵𝗲 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆 The goal of TypeScript isn't to describe what your data looks like. It's to make wrong states unrepresentable. 💬 What's a bug you hit because your state allowed something impossible? Drop it below. 👇 #TypeScript #SoftwareEngineering #WebDev #FrontendEngineering #ReactJS
To view or add a comment, sign in
-
-
TypeScript used naively adds syntax. Used correctly, it prevents entire bug classes. Here are the patterns that actually matter in production. ── Discriminated Unions ── Stop using optional fields for state that has clear phases. Instead of: { data?: User; error?: string; loading?: boolean } Use: → { status: 'loading' } → { status: 'success'; data: User } → { status: 'error'; error: string } TypeScript now narrows correctly in every branch. No more 'data might be undefined' checks scattered everywhere. ── The satisfies Operator (TS 4.9+) ── Validates a value against a type without widening it. You keep autocomplete on specific keys. You get the type safety check. Best of both worlds. ── Template Literal Types ── Generate all valid string combinations at compile time. type ApiCall = `${HTTPMethod} ${Endpoint}` TypeScript tells you when you're calling an endpoint that doesn't exist. ── Branded Types ── Two strings that are semantically different: type UserId = string & { readonly __brand: 'UserId' } type PostId = string & { readonly __brand: 'PostId' } Now you can't accidentally pass a PostId where a UserId is expected. Even though both are just strings at runtime. ── unknown over any ── any disables the type checker entirely. unknown forces you to narrow before using the value. One creates bugs. The other prevents them. TypeScript's real value: Making impossible states unrepresentable at compile time. Not just adding type annotations. #TypeScript #Frontend #JavaScript #SoftwareEngineering #WebDevelopment
To view or add a comment, sign in
-
Creating custom validators in Signal Forms is simpler than you think! In my previous articles, I talked about the built-in validation rules and async validation in Signal Forms, but what happens when you hit a highly specific business requirement? Maybe you want the password to contain a special character, or a username to not be "admin". In traditional Reactive Forms, this meant writing a custom 'ValidatorFn', digging into the 'AbstractControl' to grab the value, and returning a generic error map. Signal Forms make this incredibly elegant with the new 'validate' function. You just read the value directly from the signal. No more control.value guesswork. And since the form is driven by your data model, TypeScript knows exactly what type of data you are validating. If the data is valid, return 'null'. If it’s invalid, return a simple object with a 'kind' property and your custom message. If you want to make your validator reusable, just wrap 'validate' inside a function, and then you can use that function in any form where you want that custom validation to happen. It feels much more like writing standard, predictable JavaScript/TypeScript rather than fighting the framework. #Angular #TypeScript #WebDevelopment #Frontend #SignalForms #SoftwareEngineering
To view or add a comment, sign in
-
-
🚀 Functional Programming: Immutability (Part:2) what is Immutability? >>You do NOT change existing data — you create new data instead 📌Example ❌ Mutable (Changing Original Data) const user = { name: "Javascript" }; user.name = "React"; console.log(user); // { name: "React" } 👉 Problem: Original object is modified Can cause bugs in large apps ✅ Immutable (Creating New Data) const user = { name: "Javascript" }; const updatedUser = { ...user, name: "React" }; console.log(user); // { name: "Javascript" } console.log(updatedUser); // { name: "React" } ✔ Original data is safe ✔ New data is created 📌 Arrays Example ❌ Mutable const numbers = [1, 2, 3]; numbers.push(4); 👉 Original array is changed ✅ Immutable const numbers = [1, 2, 3]; const newNumbers = [...numbers, 4]; ✔ New array created ✔ Old array unchanged 🔥 Why Immutability Matters ✔ Predictable code ✔ Easier debugging ✔ Prevents unexpected bugs ✔ Very important in React state updates ✔ Works perfectly with pure functions #JavaScript #FunctionalProgramming #CleanCode #WebDevelopment #FrontendDevelopment #Coding
To view or add a comment, sign in
-
Have you ever found yourself struggling with data formats in JavaScript? JSON.parse and JSON.stringify are your best friends when it comes to converting data to and from JSON format. ────────────────────────────── Mastering JSON.parse and JSON.stringify Unlock the full potential of JSON in your JavaScript projects. #javascript #json #webdevelopment ────────────────────────────── Key Rules • Use JSON.stringify to convert JavaScript objects into JSON strings. • Use JSON.parse to turn JSON strings back into JavaScript objects. • Be mindful of data types; functions and undefined values cannot be stringified. 💡 Try This const obj = { name: 'Alice', age: 25 }; const jsonString = JSON.stringify(obj); const parsedObj = JSON.parse(jsonString); console.log(parsedObj); ❓ Quick Quiz Q: What does JSON.stringify do? A: It converts a JavaScript object into a JSON string. 🔑 Key Takeaway Mastering JSON methods can simplify data handling in your applications! ────────────────────────────── Small JavaScript bugs keep escaping to production and breaking critical user flows. Debugging inconsistent runtime behavior steals time from feature delivery.
To view or add a comment, sign in
-
Non-primitive data types Most JavaScript beginners learn numbers and strings first… But real power starts with non-primitive data types. 🚀 If you want to build real applications, you must understand these. In JavaScript, non-primitive data types can store multiple values and complex data. Here are the most important ones: • Object – Stores data in key–value pairs. Perfect for real-world data like users, products, or settings. • Array – Stores a list of values in a single variable. Great for lists like items, users, or tasks. • Function – A reusable block of code that performs a task. Functions are also treated as objects in JavaScript. • Date, Map, Set – Special objects used for managing time, unique values, and key-value collections. ✨ Key idea: Unlike primitive types, non-primitive types are stored by reference, which changes how copying and comparison work. Master these and your JavaScript skills will level up quickly. #JavaScript #WebDevelopment #FrontendDevelopment #ProgrammingBasics #LearnToCode #SoftwareDevelopment #JavaScriptTips #CodingForBeginners #FullStackDevelopment #TechEducation
To view or add a comment, sign in
-
-
🟨 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁 𝗗𝗮𝘆 𝟱𝟴: 𝗗𝗮𝘁𝗮 𝗡𝗼𝗿𝗺𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗶𝗻 𝗥𝗲𝗮𝗰𝘁 (𝗪𝗵𝘆 𝗡𝗲𝘀𝘁𝗲𝗱 𝗦𝘁𝗮𝘁𝗲 𝗗𝗼𝗲𝘀𝗻’𝘁 𝗦𝗰𝗮𝗹𝗲) Ever built a drag & drop UI or complex state… and updates started getting messy? 🤔 🔹 𝗪𝗵𝗲𝗿𝗲 𝗧𝗵𝗶𝘀 𝗛𝗮𝗽𝗽𝗲𝗻𝘀 APIs usually return nested data 👇 But in React, we often transform it into a normalized structure for easier updates & better performance. 🔹 𝗧𝗵𝗲 𝗣𝗿𝗼𝗯𝗹𝗲𝗺 (𝗡𝗲𝘀𝘁𝗲𝗱 𝗦𝘁𝗮𝘁𝗲) const data = [ { id: "todo", cards: [ { id: 1, title: "Fix bug" }, { id: 2, title: "Update UI" } ] }, { id: "progress", cards: [ { id: 3, title: "API work" } ] } ]; 👉 Moving a card = moving full object 😵 👉 Updating = deep nested changes ❌ 👉 Causes unnecessary re-renders in React 🔹 𝗧𝗵𝗲 𝗙𝗶𝘅 (𝗡𝗼𝗿𝗺𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻) const data = { columns: { todo: { id: "todo", cardIds: [1, 2] }, progress: { id: "progress", cardIds: [3] } }, cards: { 1: { id: 1, title: "Fix bug" }, 2: { id: 2, title: "Update UI" }, 3: { id: 3, title: "API work" } } }; 👉 Columns store only IDs 👉 Cards stored once (single source of truth) 🔹 𝗪𝗵𝗮𝘁 𝗖𝗵𝗮𝗻𝗴𝗲𝗱 (𝗥𝗲𝗮𝗰𝘁 𝗣𝗲𝗿𝘀𝗽𝗲𝗰𝘁𝗶𝘃𝗲) Before: • Deep state updates • Re-renders large parts of UI • Hard to maintain After: • Update small pieces of state ✅ • Minimal re-renders (better performance) ⚡ • Cleaner, predictable updates 🔹 𝗞𝗲𝘆 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆 👉 In React, treat state like a database • Store entities once • Reference them using IDs 👉 Drag & Drop = move IDs, not objects 💬 GitHub link in comments. #JavaScript #React #Frontend #Day58 #100DaysOfCode
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development