TypeScript 5 Updates
Latest features and improvements in TypeScript 5
🚀 TypeScript 5 New Features
TypeScript 5 brings significant improvements including decorators, const type parameters, better enums, and performance enhancements. These updates make TypeScript faster, more powerful, and easier to use while maintaining backward compatibility with existing code.
// TypeScript 5 decorator example
function logged(target: any, key: string) {
console.log(`${key} was called`);
}
Major TypeScript 5 Features
Decorators
ECMAScript decorators support
@sealed
class MyClass { }
Const Type Params
Preserve literal types
function foo<const T>(arr: T[]) {
return arr;
}
Better Enums
All enums are union enums
enum Status {
Active,
Inactive
}
Performance
Faster compilation and checks
10-20% faster builds
🔹 Decorators (Stage 3)
TypeScript 5 supports ECMAScript decorators:
🔸 Class Decorator
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class BugReport {
type = "report";
title: string;
constructor(title: string) {
this.title = title;
}
}
const bug = new BugReport("Critical Bug");
console.log(bug.title); // "Critical Bug"
🔸 Method Decorator
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with`, args);
return originalMethod.apply(this, args);
};
}
class Calculator {
@log
add(a: number, b: number): number {
return a + b;
}
}
const calc = new Calculator();
calc.add(5, 3);
// Logs: Calling add with [5, 3]
// Returns: 8
🔹 Const Type Parameters
Preserve literal types in generic functions:
🔸 Without Const
function makeArray<T>(arr: T[]) {
return arr;
}
const arr1 = makeArray([1, 2, 3]);
// Type: number[]
🔸 With Const
function makeArray<const T>(arr: T[]) {
return arr;
}
const arr2 = makeArray([1, 2, 3]);
// Type: readonly [1, 2, 3]
const colors = makeArray(["red", "green", "blue"]);
// Type: readonly ["red", "green", "blue"]
🔹 All Enums Are Union Enums
Better type checking for enums:
enum Status {
Active = "ACTIVE",
Inactive = "INACTIVE",
Pending = "PENDING"
}
function setStatus(status: Status) {
console.log(`Status set to: ${status}`);
}
setStatus(Status.Active); // OK
// setStatus("ACTIVE"); // Error in TS 5
// Enum as type
type ActiveStatus = Status.Active | Status.Pending;
function processActive(status: ActiveStatus) {
if (status === Status.Active) {
console.log("Processing active");
} else {
console.log("Processing pending");
}
}
🔹 Supporting Multiple Config Files
Extend from multiple configuration files:
// tsconfig.json
{
"extends": ["./base.json", "./strict.json"],
"compilerOptions": {
"outDir": "./dist"
}
}
🔹 Better Module Resolution
New moduleResolution options:
{
"compilerOptions": {
"moduleResolution": "bundler",
"module": "esnext",
"target": "esnext"
}
}
🔸 Import Attributes
// Import JSON with attributes
import data from "./data.json" with { type: "json" };
// Import CSS modules
import styles from "./styles.css" with { type: "css" };
console.log(data.name);
console.log(styles.container);
🔹 Improved Type Narrowing
Smarter type inference in control flow:
function processValue(value: string | number | null) {
// TypeScript 5 better understands this
if (typeof value === "string") {
console.log(value.toUpperCase());
} else if (typeof value === "number") {
console.log(value.toFixed(2));
} else {
console.log("Value is null");
}
}
// Better array filtering
const mixed: (string | number)[] = [1, "two", 3, "four"];
const strings = mixed.filter((x): x is string => typeof x === "string");
// Type: string[]
🔹 Switch (true) Narrowing
Type narrowing in switch statements:
function getArea(shape: { kind: "circle"; radius: number } | { kind: "square"; size: number }) {
switch (true) {
case shape.kind === "circle":
return Math.PI * shape.radius ** 2;
case shape.kind === "square":
return shape.size ** 2;
default:
return 0;
}
}
const circle = { kind: "circle" as const, radius: 5 };
const square = { kind: "square" as const, size: 4 };
console.log(getArea(circle)); // 78.54
console.log(getArea(square)); // 16
🔹 Performance Improvements
TypeScript 5 is faster:
- 10-20% faster compilation times
- Reduced memory usage during type checking
- Faster IDE response times
- Optimized module resolution
- Better caching for incremental builds
🔹 JSDoc @satisfies
Use satisfies in JSDoc comments:
// TypeScript
const config = {
url: "https://example.com",
port: 8080
} satisfies Config;
// JavaScript with JSDoc
/** @satisfies {Config} */
const config = {
url: "https://example.com",
port: 8080
};
🔹 Practical Example
Combining TypeScript 5 features:
// Using decorators and const type parameters
function validate(target: any, propertyKey: string) {
console.log(`Validating ${propertyKey}`);
}
class User {
@validate
name: string;
@validate
email: string;
constructor(name: string, email: string) {
this.name = name;
this.email = email;
}
}
// Using const type parameters
function createConfig<const T extends Record<string, any>>(config: T) {
return config;
}
const appConfig = createConfig({
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3
} as const);
// Type is preserved exactly
type ConfigType = typeof appConfig;
// {
// readonly apiUrl: "https://api.example.com";
// readonly timeout: 5000;
// readonly retries: 3;
// }
const user = new User("Alice", "[email protected]");
console.log(user.name);
console.log(appConfig.apiUrl);
🔹 Migration Tips
Upgrading to TypeScript 5:
-
Update TypeScript:
npm install -D typescript@latest - Review breaking changes in release notes
- Update tsconfig.json for new features
- Test your codebase thoroughly
- Enable new strict options gradually
- Update IDE extensions for best experience