Javascript
figonkingx  

TypeScript 5.5 và ES2024: Những cải tiến mới

TypeScript 5.5 được phát hành vào tháng 6/2024, mang đến những cải tiến quan trọng về type inference, performance và developer experience. Bài viết này phân tích chi tiết các tính năng mới và hướng dẫn nâng cấp.

Nội dung chính

Inferred Type Predicates – Tính năng đáng chú ý nhất

Đây là improvement lớn nhất trong TS 5.5. TypeScript giờ có thể tự động infer type predicates từ function implementation:

Trước TypeScript 5.5

// Phải khai báo explicit type predicate
function isString(x: unknown): x is string {
    return typeof x === "string";
}

const items = [1, "hello", 2, "world", null];

// Phải dùng explicit type predicate
const strings = items.filter(isString);
// strings: string[] ✅

TypeScript 5.5+

// Không cần explicit type predicate nữa!
function isString(x: unknown) {
    return typeof x === "string";
}
// TypeScript tự hiểu đây là type predicate: x is string

const items = [1, "hello", 2, "world", null];
const strings = items.filter(isString);
// strings: string[] ✅ - Tự động infer!

// Thậm chí inline arrow functions cũng work
const numbers = items.filter(x => typeof x === "number");
// numbers: number[] ✅

// Filter out nulls
const nonNull = items.filter(x => x !== null);
// nonNull: (string | number)[] ✅

Real-world examples

interface User {
    id: number;
    name: string;
    email?: string;
}

const users: (User | null)[] = [
    { id: 1, name: "Alice", email: "alice@example.com" },
    null,
    { id: 2, name: "Bob" },
];

// Trước 5.5: phải viết type guard
function hasEmail(user: User | null): user is User & { email: string } {
    return user !== null && user.email !== undefined;
}

// TS 5.5: Tự động infer!
const usersWithEmail = users.filter(user => user !== null && user.email !== undefined);
// usersWithEmail: (User & { email: string })[] ✅

Isolated Declarations

Feature mới cho phép parallel declaration emit, tăng tốc build cho large projects:

// tsconfig.json
{
  "compilerOptions": {
    "isolatedDeclarations": true,
    "declaration": true
  }
}

Tại sao cần Isolated Declarations?

Trong monorepos lớn, việc generate .d.ts files có thể chậm vì TypeScript cần analyze toàn bộ codebase. Với isolated declarations, mỗi file có thể được process độc lập.

Requirements

Để sử dụng isolated declarations, exported functions/variables phải có explicit type annotations:

// ❌ Error với isolatedDeclarations
export function add(a: number, b: number) {
    return a + b; // Return type không explicit
}

// ✅ OK
export function add(a: number, b: number): number {
    return a + b;
}

// ❌ Error
export const config = {
    port: 3000,
    host: "localhost"
};

// ✅ OK
export const config: { port: number; host: string } = {
    port: 3000,
    host: "localhost"
};

Regular Expression Syntax Checking

TypeScript 5.5 giờ validate regex syntax tại compile time:

// ❌ Error: Unterminated group
const regex1 = /hello(/;

// ❌ Error: Invalid escape
const regex2 = /\q/;

// ❌ Error: Incomplete quantifier
const regex3 = /a{/;

// ✅ Valid regex
const regex4 = /hello\s+world/gi;
const regex5 = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

Named Capture Groups

const dateRegex = /(?\d{4})-(?\d{2})-(?\d{2})/;
const match = "2024-06-15".match(dateRegex);

if (match?.groups) {
    // TypeScript biết structure của groups!
    const { year, month, day } = match.groups;
    // year: string, month: string, day: string
}

Control Flow Narrowing Improvements

function processValue(value: string | number | null) {
    if (value === null) {
        return;
    }
    
    // TS 5.5 tốt hơn trong việc track narrowed types
    if (typeof value === "string") {
        console.log(value.toUpperCase());
    } else {
        console.log(value.toFixed(2));
    }
}

// Improved narrowing with indexed access
interface Response {
    data?: {
        user?: {
            name: string;
        };
    };
}

function getName(response: Response) {
    if (response.data?.user?.name) {
        // TS 5.5 correctly narrows this
        return response.data.user.name; // string ✅
    }
    return "Unknown";
}

Performance Improvements

Faster Builds

  • ~10% faster type-checking cho average projects
  • Improved caching cho incremental builds
  • Better memory usage

Editor Performance

  • Faster completions trong VS Code
  • Improved hover information
  • Better go-to-definition

New JSDoc Support

/**
 * @import { User } from "./types"
 */

/**
 * Process a user
 * @param {User} user - The user to process
 * @returns {string} The processed result
 */
function processUser(user) {
    return user.name.toUpperCase();
}

Nâng cấp lên TypeScript 5.5

# npm
npm install typescript@5.5

# yarn
yarn add typescript@5.5

# pnpm
pnpm add typescript@5.5

Checking compatibility

# Check for breaking changes
npx tsc --noEmit

# Xem những warnings mới
npx tsc --noEmit 2>&1 | grep -i "error\|warning"

Migration tips

1. Leverage inferred type predicates

// Trước: Nhiều explicit type guards
function isNotNull(value: T | null): value is T {
    return value !== null;
}

// Sau: Có thể bỏ nhiều type guards
// TypeScript tự infer từ filter conditions

2. Adopt isolatedDeclarations gradually

// Bắt đầu với strict: false
{
  "compilerOptions": {
    "isolatedDeclarations": true,
    // Fix lỗi dần dần
  }
}

ES2024 Features Support

TypeScript 5.5 hỗ trợ đầy đủ ES2024:

// Object.groupBy
const people = [
    { name: "Alice", age: 25 },
    { name: "Bob", age: 30 },
    { name: "Charlie", age: 25 },
];

const byAge = Object.groupBy(people, person => person.age);
// { 25: [...], 30: [...] }

// Map.groupBy
const map = Map.groupBy(people, person => person.age);

// Promise.withResolvers
const { promise, resolve, reject } = Promise.withResolvers();
// Thay vì pattern phức tạp với new Promise

Fullstack Station Tips

TypeScript 5.5 là một solid release. Những điểm mình recommend:

  • Inferred type predicates – Game changer! Giảm boilerplate đáng kể khi dùng filter, find
  • Regex checking – Catch bugs sớm, đặc biệt hữu ích cho validation code
  • Isolated declarations – Xem xét cho large monorepos để tăng tốc build
  • ES2024 – Object.groupBy và Promise.withResolvers rất tiện

Upgrade path khá smooth – hầu hết projects nâng cấp không có breaking changes. Chỉ cần chú ý nếu bạn có custom type guards không cần thiết nữa.

Tham khảo

Comments

Leave A Comment