Typescript Advanced – Phần 1 – Core Principles

📌 Tổng quan

Chương này đưa bạn đến phần nâng cao của TypeScript, gồm:

  • 🔧 Các kiểu dữ liệu nâng cao (advanced types) như Partial, Pick, Omit, Record, Required,… giúp tăng độ chính xác và an toàn cho code.
  • 🧠 Giới thiệu design patterns trong TypeScript.
  • 🌐 Cách phát triển ứng dụng TypeScript trong môi trường trình duyệtserver.
  • ⚙️ So sánh và sử dụng các công cụ như Vite, React, Express.js, Nest.js, Deno, và Bun.js.

🧩 Các kiểu dữ liệu tiện ích (Utility Types)

🔹 Record<K, T>

  • Cho phép định nghĩa đối tượng mà key là K và value là T.
  • Thường dùng cho object cấu hình hoặc thống kê.

🔹 Partial<T>

  • Biến mọi thuộc tính trong T thành tùy chọn.
  • Phù hợp khi xử lý dữ liệu không đầy đủ, như input form.

🔹 Required<T>

  • Ngược với Partial, bắt buộc mọi thuộc tính.
  • Dùng để đảm bảo object đầy đủ trước khi thực thi logic.

🔹 Pick<T, K>

  • Chọn một vài thuộc tính K từ kiểu T.
  • Dùng để tạo kiểu nhỏ gọn từ một kiểu lớn hơn.

🔹 Omit<T, K>

  • Loại bỏ một vài thuộc tính K khỏi kiểu T.
  • Hữu ích khi muốn xử lý object mà không cần tất cả field.

📝 Lưu ý: PartialRequired không áp dụng đệ quy (nested objects cần chỉ rõ).


🔍 Các kỹ thuật kiểm tra và biến đổi kiểu nâng cao

🔹 keyof

  • Trích ra tập hợp key của một interface.
  • Dùng để tạo logic tổng quát hơn, ví dụ cập nhật form field.

🔹 Branded Types

  • Dùng để phân biệt kiểu có cấu trúc giống nhau.
  • Tạo bằng cách thêm thuộc tính ẩn (__type: Brand).

🔹 Conditional Types

  • Cho phép định nghĩa kiểu theo điều kiện, như A extends B ? C : D
  • Kết hợp tốt với infer để truy xuất kiểu nội dung như:
    • UnpackBox<{ value: 10 }> => number
    • DeepUnpack<Box<Box<string>>> => string

🔹 Mapped Types

  • Biến đổi các thuộc tính của một kiểu:
    • Thêm tùy chọn: [P in keyof T]?: T[P]
    • Đổi tên key: [P in keyof T as product ${P}]: string

🧭 TypeScript trong trình duyệt (browser)

🛠️ DOM & HTML

  • DOM là cây các phần tử HTML mà ta thao tác bằng JS/TS.
  • TypeScript cung cấp typing mạnh như HTMLElement, HTMLButtonElement để tránh lỗi truy cập thuộc tính.

⚙️ Công cụ hỗ trợ

  • Bundler như Webpack, Vite giúp:
    • Biên dịch, gom file, tối ưu performance
    • Hỗ trợ phát triển frontend hiện đại

💡 Ví dụ

  • Dựng DOM tree từ HTML
  • Sử dụng querySelector, createElement, addEventListener

📦 Dự án mẫu sử dụng Vite

  • Tạo: npx create-vite@latest my-app --template vanilla-ts
  • Build: npm run build
  • Preview: npm run preview

⚛️ TypeScript với React

✅ 3 cách định nghĩa component:

  • React.FC<Props>
  • Function với props: Props
  • Dùng PropsWithChildren<Props> để truyền children

💡 Ví dụ

const Greeting: React.FC<{ name: string }> = ({ name }) => <h1>Hello, {name}!</h1>

⚙️ Cấu hình cần thiết

  • "jsx": "react-jsx" trong tsconfig
  • lib: ["DOM", "DOM.Iterable"]

🖥️ TypeScript trong môi trường server

🔥 Các runtime phổ biến

  • Node.js: phổ biến, nhiều package
  • Deno: chạy trực tiếp TypeScript
  • Bun: hiệu suất cao, hỗ trợ TS

⚙️ Server mẫu

  • Deno.serve(...)Bun.serve(...)
  • Khởi chạy và lắng nghe trên port cụ thể

🛑 Xử lý shutdown

  • Bắt SIGINT, SIGTERM để tắt server an toàn
  • Ví dụ: process.on("SIGINT", shutdownHandler)

📊 Quản lý tiến trình

  • Dùng pm2, nodemon để tự động restart server

🚀 Framework hỗ trợ server

📌 Express.js

  • Cú pháp đơn giản, phổ biến
app.get("/health", (req, res) => res.send("OK!"));

📌 Nest.js

  • Cấu trúc module rõ ràng, giống Angular
  • Hỗ trợ DI, middleware, decorator
@Controller() export class AppController {
  @Get("/health") getHealth() { return "OK!"; }
}

⚠️ Xử lý lỗi (Error Handling)

✅ Custom Error Class

  • Kế thừa Error, thêm name rõ ràng

🔁 Union Type cho lỗi

  • Dùng { success: true | false, value | error } để kiểm soát luồng rõ ràng

🧰 Middleware lỗi chung

app.use((err, req, res, next) => {
  res.status(500).json({ error: err.message });
});

Để lại một bình luận