Bài 9. Mô-đun, tệp khai báo và cấu hình tsconfig

Dự án thật gồm nhiều tệp và thư viện. Bài này giải thích hệ mô-đun ES, tệp khai báo .d.ts, gói @types và các tùy chọn tsconfig quan trọng; cùng các cách chạy TypeScript hiện nay.

45 phútTrung cấp
Bạn sẽ học được
  • Tổ chức mã bằng import/export và import type
  • Hiểu tệp .d.ts và gói @types
  • Đọc hiểu và cấu hình tsconfig.json
  • Chọn cách chạy TS: tsc, Node.js, tsx, Vite
Thuật ngữ cần biết
ES Module
Chuẩn mô-đun của JavaScript với import/export.
.d.ts
Tệp chỉ chứa khai báo kiểu, không có mã chạy.
DefinitelyTyped
Kho cộng đồng cung cấp gói @types/... cho thư viện JS.
Type stripping
Xóa chú thích kiểu để chạy trực tiếp như JS.

Khái niệm và lý thuyết

Mỗi tệp có import/export là một mô-đun với phạm vi riêng. Khi bạn import thư viện JS, TS cần biết kiểu của nó: thư viện hiện đại thường kèm sẵn .d.ts; thư viện cũ thì cài thêm @types/ten-thu-vien.

Từ 2025–2026, cách chạy TypeScript thay đổi nhiều: Node.js chạy trực tiếp tệp .ts bằng cơ chế xóa kiểu (type stripping); TypeScript 7 có trình biên dịch viết lại bằng Go, nhanh hơn khoảng 10 lần. Vai trò của tsc ngày càng tập trung vào kiểm tra kiểu (tsc --noEmit), còn việc chạy/đóng gói do Node.js, Vite, esbuild đảm nhận.

import và export

// toan.ts
export function tong(a: number, b: number) { return a + b; }
export type Diem = { x: number; y: number };
export default class MayTinh {}

// main.ts
import MayTinh, { tong } from "./toan.js";
import type { Diem } from "./toan.js"; // chỉ lấy kiểu

Với "module": "nodenext", đường dẫn import tương đối cần đuôi .js (hoặc .ts khi bật allowImportingTsExtensions).

Tệp khai báo

// globals.d.ts: khai báo biến toàn cục do script ngoài tạo ra
declare const APP_VERSION: string;

// Bổ sung kiểu cho mô-đun chưa có kiểu
declare module "thu-vien-cu" {
  export function lamGi(x: string): number;
}
npm install lodash
npm install -D @types/lodash

tsconfig.json khuyến nghị

{
  "compilerOptions": {
    "target": "es2022",
    "module": "nodenext",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "verbatimModuleSyntax": true,
    "skipLibCheck": true,
    "outDir": "dist"
  },
  "include": ["src"]
}
Tùy chọnTác dụng
strictBật toàn bộ kiểm tra nghiêm ngặt
noUncheckedIndexedAccessTruy cập chỉ mục có thể là undefined
verbatimModuleSyntaxBắt buộc import type rõ ràng
skipLibCheckBỏ kiểm tra .d.ts thư viện, build nhanh hơn

Các cách chạy TypeScript

CáchLệnhPhù hợp
tscnpx tscBiên dịch ra JS, kiểm tra kiểu
Node.jsnode app.tsScript, công cụ dòng lệnh
tsxnpx tsx watch app.tsPhát triển nhanh, có watch
Vitenpm create vite@latestỨng dụng web front-end
Mẹo hay

Thêm script "typecheck": "tsc --noEmit" vào package.json và chạy trong CI để mọi commit đều được kiểm tra kiểu.

Lưu ý

Khi chạy bằng type stripping, các cú pháp sinh mã như enum, namespace, parameter property không được hỗ trợ mặc định; bật erasableSyntaxOnly để TS cảnh báo sớm.

Thực hành
  1. Tách dự án thành src/types.ts, src/utils.ts, src/main.ts.
  2. Cài một thư viện cũ và gói @types tương ứng, xem gợi ý kiểu trong VS Code.
  3. Viết globals.d.ts khai báo biến APP_VERSION.
  4. Chạy cùng một tệp bằng tsc, node và tsx, so sánh.
Tóm tắt bài học
  • Mỗi tệp là một mô-đun; dùng import type cho kiểu.
  • .d.ts và @types cung cấp kiểu cho thư viện JS.
  • strict và các tùy chọn bổ sung giúp mã an toàn.
  • tsc lo kiểm tra kiểu; Node.js/Vite lo chạy.