AI

TypeScript 5.5: The Features I Actually Care About

TypeScript 5.5 dropped quietly but it's packed with changes that'll make you rethink how you've been writing type guards. I've been digging through the release notes so you don't have to, and honestly? Some of this stuff is genuinely exciting.

TypeScript 5.5: The Features I Actually Care About

I've been writing TypeScript professionally since version 2.8, back when conditional types landed and everyone collectively lost their minds trying to understand infer. I've watched this language grow from "JavaScript with a spell-checker" into something that can genuinely catch entire categories of bugs before your code ever touches a runtime. TypeScript 5.5 continues that trend, and there are a few specific additions here that I think deserve more attention than they're getting.

Inferred Type Predicates: Finally

Look, this is the one. This is the feature I've been quietly wishing for since probably 2019. Before 5.5, if you filtered an array and TypeScript couldn't figure out the resulting type, you were writing manual type guards like some kind of animal. Something like this was a daily frustration:

const values = [1, 2, null, 3, null];
const numbers = values.filter(x => x !== null);
// TypeScript: numbers is (number | null)[]
// Me: WHAT

You'd end up writing x is number annotations by hand, which is fine, but it's boilerplate that shouldn't exist. TypeScript 5.5 now infers type predicates from function bodies automatically. That same filter call now correctly resolves to number[]. No manual annotation. The compiler just... figures it out.

I actually ran into the old behavior in a particularly painful way at a previous job. We had a data pipeline at a fintech startup that was filtering a massive union type from an API response, and a junior dev on the team kept wondering why the TypeScript errors wouldn't go away even after the null check. We spent two hours in a Slack thread before someone finally posted the manual type predicate workaround. Two hours. For something the compiler should have been doing all along. That story has a happy ending now.

The New Set Methods Are Typed (And It Matters More Than You Think)

TypeScript 5.5 adds proper typings for the new ECMAScript Set methods: union, intersection, difference, and symmetricDifference. These methods are already shipping in Chrome 122 and Node 22, and now TypeScript actually knows about them.

Here's the thing: if you've been doing set math with arrays and filter calls, please stop. The new native methods are cleaner and TypeScript will now guide you through using them correctly. Your future self will be grateful.

const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
const result = a.intersection(b);
// TypeScript knows result is Set<number>

Isolated Declarations: The Monorepo Game-Changer

This one is specifically for people working in large monorepos, and I know that's not everyone, but if it's you, pay attention. The new isolatedDeclarations compiler option requires that every exported declaration has an explicit type annotation. That sounds annoying at first. It kind of is. But the payoff is that build tools like Oxc and ESBuild can now generate declaration files without needing to do a full TypeScript type-check pass, which means your d.ts file generation gets dramatically faster.

Microsoft and Vercel both seem pretty excited about this, and I get why. When you're working with a monorepo that has 200 packages and your declaration emit is the bottleneck in CI, shaving 40% off that time is not nothing. It's actually a lot.

The tradeoff is real though. You're adding annotation overhead to your source code. It's a deliberate performance versus convenience trade, and I think the TypeScript team made the right call by making it opt-in rather than forcing it on everyone.

Regular Expression Syntax Checking

Honestly I did not have this on my 2024 TypeScript bingo card. The compiler now actually parses your regex literals and tells you when they're invalid. How many times have you shipped a broken regex to production because the runtime was the first thing that ever actually read it? TypeScript will now catch /(? before it ever gets there.

It's not a full regex linter, it won't catch logic errors in your patterns, but catching syntax errors at compile time rather than runtime is exactly the kind of thing TypeScript should be doing. Small feature, high value.

Performance Improvements Across the Board

The 5.5 release notes mention significant performance improvements to type checking speed, particularly around control flow analysis. In my experience switching over a mid-sized project at about 80k lines of TypeScript, the language server felt noticeably snappier in VS Code. That's subjective, I know, but the benchmarks from the TypeScript team back it up. Some pathological cases that were hitting multiple seconds on type check are now measuring in the hundreds of milliseconds.

That matters for developer experience. A fast feedback loop is the difference between a team that loves TypeScript and a team that turns on skipLibCheck and slowly starts defaulting everything to any. Speed is a feature.

Should You Upgrade?

Yes. Right now. TypeScript is one of those dependencies where staying on an old version costs you real productivity and the upgrade path is almost always smooth. Run npm install typescript@5.5, fix the three warnings your linter throws, move on with your life. The inferred type predicates alone are worth the five minutes it takes.

TypeScript 5.5 isn't a flashy release with a single marquee feature, but that's not a criticism. It's a release full of things that make the day-to-day better. That's what good software engineering looks like.

OPEN IN REEDL_ FEED →← Back to feed