TypeScript 5.5 at a Glance
TypeScript 5.5 is a quality-of-life release focused on eliminating boilerplate, speeding up large codebases, and catching more bugs at the syntax level. The standout feature — inferred type predicates — closes a gap that has frustrated TypeScript developers for years.
Inferred Type Predicates
Previously, if you wrote a filter function, TypeScript could not narrow the resulting array type automatically. You had to write an explicit type predicate:
// TypeScript 5.4 — you had to write the type predicate manually
function isString(x: unknown): x is string {
return typeof x === "string";
}
const mixed: (string | number)[] = ["a", 1, "b", 2];
const strings = mixed.filter(isString); // string[]
In TypeScript 5.5, TypeScript infers the type predicate from the function body. You no longer need to annotate it:
// TypeScript 5.5 — inferred automatically
function isString(x: unknown) {
return typeof x === "string";
}
const strings = mixed.filter(isString); // string[] ✓ inferred correctly
// Works with arrow functions too
const onlyUsers = items.filter((item): item is User => item.type === "user");
// Now just:
const onlyUsers = items.filter(item => item.type === "user"); // User[]
This works for any function where TypeScript can trace the return type back to a type check. It handles typeof, instanceof, discriminated union checks, and more.
--isolatedDeclarations for Monorepos
Large monorepos with hundreds of packages spend significant build time computing declaration files. --isolatedDeclarations enforces that every exported symbol has an explicit type annotation, enabling parallel declaration generation without cross-package analysis:
{
"compilerOptions": {
"isolatedDeclarations": true,
"declaration": true
}
}
// Error with --isolatedDeclarations: return type must be explicit
export function getUser(id: string) { // ✗
return db.users.findOne(id);
}
// Correct
export function getUser(id: string): Promise<User | null> { // ✓
return db.users.findOne(id);
}
The payoff: build tools like Turborepo and Vite can now generate .d.ts files for each package in parallel, cutting declaration emit time by 50%+ on large monorepos.
Regular Expression Syntax Checking
TypeScript 5.5 parses regex literals and reports syntax errors inside the editor. No plugin needed:
const pattern = /(?<=foo)bar/; // ✓ valid lookbehind
const broken = /(?<=)/; // ✗ Error: Invalid regular expression
const named = /(?<year>d{4})/; // ✓ named capture group recognized
This catches typos in regex that previously only surfaced at runtime.
Performance Improvements
TypeScript 5.5 ships a number of internal compiler improvements:
- ~50% faster type checking on large codebases in common patterns
- Faster
--watchmode for incremental builds - Reduced memory usage for large union types
- Monomorphic object shapes for the checker's internal structures
Benchmark on a 500k-line codebase: full tsc --noEmit went from 42s → 28s.
@satisfies Tag in JSDoc
The satisfies operator (added in 5.0) is now available in JSDoc for plain JavaScript projects:
/** @type {import('./types').Config} */
const config = /** @satisfies {import('./types').Config} */ ({
port: 3000,
host: "localhost",
});
Upgrading
pnpm add -D typescript@5.5
5.5 has no breaking changes for most codebases. The one edge case: if you had functions that accidentally returned different types in different branches, TypeScript may now infer a more precise type that surfaces previously hidden errors. These are real bugs — fix them.
References: TypeScript 5.5 announcement · playground