There’s one very important gotcha with Conditional Types in TypeScript that catches almost everyone at some point. It’s called 'Distributivity.' At first, conditional types feel predictable. You write a condition. TypeScript checks it. You get a result. But when union types enter the picture, things suddenly behave very differently. The core idea that you need to understand is - Conditional types distribute over union types, but only in very specific situations. So, what does 'distribute' actually mean? When a conditional type is written using a generic type parameter, and that parameter is later given a union, TypeScript doesn’t check the union as a whole. Instead, it applies the condition to each member of the union individually, and then unions the results back together. This behavior is extremely powerful, but also very easy to misunderstand if you don’t know it exists. Now here’s the subtle part that causes confusion. Distributivity only happens when the conditional type is applied to a generic type parameter. If you write a conditional type directly against a union type, TypeScript does not distribute. In that case, TypeScript checks the union as a single unit. And if any member of that union fails the condition, the entire check fails. That’s why two conditional types that look almost identical can produce completely different results. One distributes. The other doesn’t. This distinction explains a lot of "why did this become 'never'?" moments when working with conditional types. There’s also an important escape hatch. If you don’t want distributive behavior, you can explicitly turn it off by wrapping the type in a tuple. This tells TypeScript: 'Treat this as one thing, not a union of things.' And interestingly, you can also force distribution in situations where you’re not using a type parameter, by introducing one via 'infer.' At that point, TypeScript is back in a generic context, and distributivity kicks in again. The key takeaway is that Conditional types don’t behave differently by accident. They behave differently based on how you write them. Once you understand when distributivity applies, and when it doesn’t, a lot of confusing behavior suddenly becomes predictable. #TypeScript #JavaScript #Programming #Coding #WebDevelopment
Distributivity in Conditional Types in TypeScript
More Relevant Posts
-
🧠 The bug that cost me 3 hours… and taught me (again) how TypeScript lies to you Today I spent almost 3 hours debugging something that made absolutely no sense. Same DTO. Same ValidationPipe. Same endpoint structure. ✅ Works perfectly in one place. ❌ Completely breaks in another. The logs were weird: DTO looked like a function JSON.stringify() returned undefined ValidationPipe kept throwing BadRequestException request body existed, but DTO fields were undefined Everything looked correct. So naturally: checked pipes checked middleware checked request payload blamed NestJS blamed class-validator questioned life decisions The confusing part? The exact same logic worked elsewhere in the project. After digging through pipes, decorators, and request lifecycle… the problem turned out to be one single word: import type { UpdateUserByAdminDTO } from "../dto/admin-user.dto"; Yep. import type. TypeScript removes type-only imports at runtime. But NestJS needs DTO classes at runtime for validation, transformation, and metadata reflection. So ValidationPipe wasn’t receiving a class — it was receiving… nothing useful. Changing it to: import { UpdateUserByAdminDTO } from "../dto/admin-user.dto"; Fixed everything instantly. Lesson (that I apparently need to relearn every few months): If a class is used by: decorators ValidationPipe Swagger helpers (PartialType, OmitType) class-validator class-transformer 👉 it is NOT a type. It’s runtime code. And import type will silently break it. Sometimes the hardest bugs are not complex ones. They’re the ones where everything looks correct. And the fix is one deleted word. #TypeScript #NestJS #BackendDevelopment #SoftwareEngineering #Debugging #WebDevelopment #ProgrammingLife #Developers #LessonsLearned #Coding
To view or add a comment, sign in
-
-
Most TypeScript devs write types that describe shape. 'Branded Types' let you write types that enforce intent. In my last post, we saw how TypeScript's structural type system can let logic errors slip through unnoticed. Same shape = same type, even when they mean completely different things. So how do we fix that? Enter 'Branded Types.' The idea is simple: take any base type and attach an invisible "brand" to it, a unique marker that exists purely at the type-level. Two types might look structurally identical, but if they carry different brands, TypeScript treats them as incompatible. Think of it like a stamp on a document. The paper looks the same. The content might look the same. But without the right stamp, it's not valid. The best part? This costs you nothing at runtime. Branded types are a compile-time construct only. No extra objects, no performance overhead. Just stronger guarantees from your type-checker. This pattern shines in situations where plain primitives aren't expressive enough. Passwords vs plain strings. User IDs vs order IDs. Verified emails vs unverified ones. Anywhere you want TypeScript to stop treating two things as interchangeable just because they share a shape. It's one of those techniques that feels like a workaround at first, but once it clicks, you start seeing exactly where it belongs in your codebase. #TypeScript #Programming #Coding #WebDevelopment #JavaScript
To view or add a comment, sign in
-
-
🚀 Day 1 of learning TypeScript — Started from scratch today, diving into the basics of TS. Here's what I picked up on Day 1: ✅ TypeScript is essentially a wrapper on top of JavaScript — it adds a layer, compiles down to .js, and then runs via Node.js ✅ What JS doesn't have (but TS does): → Interfaces → Generics → Abstraction (Abstract classes & Interfaces) → Data-type safety ✅ Primitive Data Types in TS: number | string | boolean | null | undefined ✅ Non-primitive types: object & function — with proper type annotations! ✅ Syntax difference that got me: JS: let age = 97 TS: let age: number = 97 Such a small change, but it makes the code SO much more readable and safe. ✅ Key insight: Even if TS throws a compile-time error, it still generates the .js file — because JS doesn't care about types. The compile-time error is TS doing YOU a favor. 💡 The journey of a thousand lines of code begins with a single type annotation. 😄 Day 1 ✅ — many more to go! #TypeScript #JavaScript #LearningInPublic #Programming #Testing #CodingJourney
To view or add a comment, sign in
-
-
TypeScript is a powerful, statically-typed superset of JavaScript that helps you write safer and more maintainable code. And this course teaches you all the fundamentals so you can start using it in your projects. You'll learn about built-in types, type annotation, arrow functions, union, literal, and nullable types, enums, interfaces, and lots more. https://lnkd.in/gwSCzXr5
To view or add a comment, sign in
-
-
🚀 Day 5 of Learning TypeScript ✅ Today I unlocked one of TypeScript's most powerful features: Generics! 🔥 This is a game-changer for writing reusable, type-safe code. The Problem I Solved: I started by writing separate functions for finding max numbers and max strings: typescript function findMaxNumber(array: number[]): number { ... } function findMaxString(array: string[]): string { ... } Same logic, different types. That's code duplication! 😫 The Solution: Generics typescript function findMax<T>(array: T[]): T { return array.reduce((max, item) => (item > max ? item : max)); } const maxNumber = findMax<number>([1, 3, 2]); // 3 const maxString = findMax<string>(["a", "b", "c"]); // "c" One function that works with ANY type! The <T> is like a placeholder that gets filled in when you use the function. What I Learned: Generic Functions - Write once, use with any type. TypeScript infers the type automatically! Generic Classes - Created a Container<T> class that can hold any type of value. Same class works for numbers, strings, objects - anything! Generic Interfaces - Interfaces can be generic too! Perfect for defining flexible contracts. Type Inference - Often you don't even need to specify <number> or <string> - TypeScript figures it out from the values you pass! Real-World Use Cases: ✅ Array operations (filter, map, reduce) ✅ API response wrappers ✅ Database query builders ✅ Cache systems ✅ Form handlers Why This Matters: Before generics: Write 10 similar functions for 10 different types With generics: Write 1 function that works with all types DRY (Don't Repeat Yourself) + Type Safety = 🎯 Generics let me write flexible code without sacrificing TypeScript's safety. This is the kind of feature that separates beginners from pros! #TypeScript #WebDevelopment #SoftwareEngineering #Programming #CodeNewbie #DeveloperCommunity #TechTwitter #100DaysOfCode #LearnToCode #JavaScript
To view or add a comment, sign in
-
-
Just published a new blog on Arrow Functions in JavaScript 🚀 Covered: • Basic arrow function syntax • One vs multiple parameters • Implicit vs explicit return • Difference from normal functions • Practical examples using map() Arrow functions make your JavaScript cleaner and more modern 💻 If you're learning JS, this concept is essential. Read the full article here 👇 👉 https://lnkd.in/gWsG9j46 Hitesh Choudhary Piyush Garg Chai Aur Code Jay Kadlag Akash Kadlag Anirudh J. #JavaScript #WebDevelopment #ES6 #WebDev #Blog #FrontendDevelopment #FrontendDeveloper #Coding #Frontend #Beginners #LearnToCode #Consistency #100DaysOfCode #CodingJourney #ContinuousLearning #Learning #LearningJourney #LearnInPublic #LearningInPublic #chaicode #ChaiCode #Cohort #Cohort26 #Cohort2026
To view or add a comment, sign in
-
-
Exacting for TypeScript 7, which is coming this summer—and it's 10x faster. The compiler is being completely rewritten in Go (codenamed "Project Corsa"), and early benchmarks are wild: • VS Code codebase: 77.8s → 7.5s (10.4x speedup) • Playwright: 11.1s → 1.1s (10.1x faster) • TypeORM: 17.5s → 1.3s (13.5x faster) What this actually means: ✅ Editor startup drops from ~10 seconds to ~1 second ✅ Auto-imports, go-to-definition, rename—all instant ✅ CI builds that actually finish before your coffee gets cold ✅ Memory usage roughly cut in half Why Go and not Rust? The TypeScript team chose Go because its patterns closely mirror existing TypeScript code, making the port line-for-line compatible. Plus, goroutines handle the heavy AST traversal and type-checking parallelism that JavaScript's single-threaded event loop After years of "TypeScript is slow" complaints in large monorepos, this changes everything. The language service was the last bottleneck—now it's about to become the fastest part of your stack. #TypeScript #JavaScript #WebDevelopment #DeveloperExperience #Programming #TechNews #Microsoft #GoLang
To view or add a comment, sign in
-
🚀 JavaScript Tip: Say Goodbye to “Try-Catch Hell” in 2026! If your code still feels like a pyramid of nested try-catch blocks just to handle a simple API call, you’re doing things the old-school way. The Safe Assignment Operator (?=) is changing how JavaScript handles errors by treating them as data instead of exceptions that interrupt your flow. Instead of wrapping everything in try-catch, you can now assign results in a cleaner, more linear way — while still capturing errors in a predictable format. Why developers are switching: ✅ No more deep nesting ✅ No more declaring variables outside blocks just to use them later ✅ Code stays top-to-bottom and easier to follow ✅ Feels similar to Go and Rust’s “error as value” approach So what about you — are you still using traditional try-catch for most cases, or have you started moving to safe assignments? 👇 #JavaScript #WebDev #Coding #SoftwareEngineering #CleanCode #Programming #ReactJS #TechTrends
To view or add a comment, sign in
-
-
One JavaScript concept that separates beginners from experienced developers: Understanding closures. At first, it feels confusing. But once it clicks — you start seeing it everywhere: • Event handlers • Callbacks • Memoization • Private state Closures aren’t magic. They’re just functions remembering their surrounding scope. Mastering this one concept unlocks a deeper understanding of how JavaScript really works. Which JS concept took you the longest to fully understand? #javascript #frontenddeveloper #webdevelopment #coding #softwareengineering
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