Giới thiệu và Cài đặt TypeScript 7.0 RC
1. TypeScript là gì?
TypeScript = JavaScript + static type system. Code TS được compile → JavaScript, sau đó JS chạy như bình thường. Type chỉ tồn tại ở compile-time, không có runtime overhead. Microsoft phát triển, mã nguồn mở.
Từ TS 7.0 (June 2026): compiler được viết lại hoàn toàn bằng Go (Project Corsa), do chính Anders Hejlsberg dẫn dắt — thay đổi kiến trúc lớn nhất trong 14 năm lịch sử TypeScript.
- Bắt bug sớm ở compile thay vì runtime.
- Autocomplete, refactor cực mạnh trong IDE (VS Code + Native Preview).
- Self-documenting code — type là tài liệu sống.
- Mở rộng từ vài file → monorepo lớn vẫn quản lý được.
- Từ 2026: compile 10× nhanh hơn với Go, developer experience vượt trội.
2. THE BIG STORY: Project Corsa — Compiler Go
Bối cảnh
Tháng 3/2026, nhóm TypeScript tại Microsoft công bố Project Corsa: viết lại toàn bộ compiler TypeScript bằng ngôn ngữ Go. Đây là thay đổi kiến trúc lớn nhất kể từ khi TypeScript ra đời năm 2012.
- TS 6.0 (March 2026): Bản transition — compiler JavaScript cuối cùng. Giới thiệu các deprecation warning, strict default, ESM default.
- TS 7.0 RC (June 18, 2026): Compiler Go (
tsgo) chính thức ra mắt ở dạng Release Candidate. Stable dự kiến July 2026. - TS 7.1 (dự kiến): Programmatic API ổn định cho tsgo.
Hiệu năng — 10× nhanh hơn
| Project | TS 6 (tsc) | TS 7 (tsgo) | Nhanh hơn |
|---|---|---|---|
| VS Code (1.5M dòng) | 77.8s | 7.5s | 10.4× |
| Sentry | 133s | 16s | 8.2× |
| TypeORM | 17.5s | 1.3s | 13.5× |
| Playwright | 11.1s | 1.1s | 10.1× |
- Memory giảm ~50%.
- LSP command failure rate chỉ bằng 1/20 so với TS 6.
- Editor startup nhanh hơn ~8×.
Vì sao chọn Go?
- Functional code structure map tự nhiên từ codebase TypeScript gốc.
- Native machine code → không JIT overhead như Node.js.
- Goroutines + shared memory → parallel thực sự (dùng hết CPU cores).
- Garbage collection tự động, phù hợp workload không latency-sensitive.
- Cả 2 codebase JS và Go được maintain song song trong quá trình transition.
CLI flags mới trong tsgo
# Parallel type-checking với N worker threads (mặc định 4)
tsgo --checkers 8
# Parallel project reference builders cho monorepo
tsgo --build --builders 4
# Force single-thread mode (debug)
tsgo --singleThreaded
# Watch mode — rebuilt với Go port của @parcel/watcher
tsgo --watch
Defaults mới (kế thừa từ TS 6.0)
| Setting | Giá trị mặc định | Ghi chú |
|---|---|---|
strict | true | Không cần khai báo nữa! |
module | "esnext" | ESM là first-class |
target | ES stable hiện tại | Không còn ES5! |
types | [] | Không auto-discover @types/* |
noUncheckedSideEffectImports | true | Bắt lỗi side-effect import |
stableTypeOrdering | true | Không thể tắt — type ordering ổn định |
rootDir | Thư mục chứa tsconfig | Không tự infer nữa |
Bị xóa — hard errors trong TS 7.0
Các option sau không compile được trong TS 7.0 (đã deprecated từ TS 6.0):
| Bị xóa | Thay thế / Ghi chú |
|---|---|
target: "es5" | Dùng Babel hoặc swc sau khi TS compile |
downlevelIteration | Không còn ý nghĩa khi không có ES5 |
module: "amd" / "umd" / "systemjs" / "none" | Chỉ còn esnext, node16, nodenext, preserve |
moduleResolution: "node" / "node10" / "classic" | Dùng bundler, node16, hoặc nodenext |
baseUrl | Dùng explicit paths |
Import assertions (assert) | Phải dùng with keyword |
preserveConstEnums | Không còn được hỗ trợ |
JSDoc @enum trong .js | Không còn hiệu lực |
TS 6 compatibility — side-by-side
Package @typescript/typescript6 cung cấp binary tsc6 để chạy song song với tsgo:
npm install -D @typescript/typescript6
npx tsc6 --noEmit # type-check bằng compiler JS cũ
npx tsgo --noEmit # type-check bằng compiler Go mới
Hữu ích khi: tooling chưa hỗ trợ tsgo (typescript-eslint, ts-jest, ts-node) hoặc cần programmatic API.
3. Cài đặt
Project mới
npm init -y
npm install -D typescript@rc @types/node
npx tsc --init # tạo tsconfig.json
Dùng compiler Go (tsgo)
# Cài native preview
npm install -D @typescript/native-preview
# Build bằng Go compiler
npx tsgo --build tsconfig.json
# Type-check bằng Go compiler
npx tsgo --noEmit
# Watch mode nhanh hơn
npx tsgo --watch
Run TS thẳng (không build)
# tsx — nhanh, vẫn hoạt động tốt
npm install -D tsx
npx tsx src/index.ts
# Node.js native type stripping (Node 23+ stable)
node src/index.ts # --strip-types là default từ Node 23
node --experimental-strip-types src/index.ts # Node 22.6+
tsgo hoặc bundler (Vite, esbuild, swc).Hello World
// src/hello.ts
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("TypeScript 7.0"));
npx tsgo # compile bằng Go compiler
node dist/hello.js
Lộ trình migration lên TS 7.0
- Upgrade lên TS 6.0 trước — tất cả deprecation sẽ hiện warning.
- Fix tất cả warning. Kiểm tra
target: es5,baseUrl,module: amd, import assertions, v.v. - Cài tsgo song song với tsc:
npm install -D @typescript/native-preview
- Chạy cả 2 trong CI đến khi output khớp:
npx tsc --noEmit && npx tsgo --noEmit
- Switch hoàn toàn sang tsgo khi mọi thứ ổn định.
Hạn chế của TS 7.0 RC
| Hạn chế | Chi tiết |
|---|---|
| Programmatic API | Ổn định trong TS 7.1, chưa sẵn sàng trong RC |
--declarationMap | Chưa hỗ trợ trong tsgo |
| ts-node / ts-jest | Không tương thích với tsgo — giữ TS 6 để chạy test/script |
| ts-morph | Chưa tương thích — cần programmatic API |
| typescript-eslint | Giữ TS 6 cho linting — chưa hỗ trợ tsgo |
4. tsconfig.json — file quan trọng nhất
{
"compilerOptions": {
/* === Type checking (strict là MẶC ĐỊNH từ TS 6.0) === */
// "strict": true, // MẶC ĐỊNH TRUE — không cần khai báo nhưng nên để rõ ràng
"noUnusedLocals": true,
"noUnusedParameters": true,
"noUncheckedIndexedAccess": true, // arr[i] trả T | undefined
"exactOptionalPropertyTypes": true, // phân biệt thiếu key vs key = undefined
/* === Module (ESM là MẶC ĐỊNH) === */
// "module": "esnext", // MẶC ĐỊNH từ TS 6.0
"moduleResolution": "bundler", // bundler/node16/nodenext — node/classic đã bị xóa!
// "target": "ES2025", // MẶC ĐỊNH theo ES stable hiện tại
"lib": ["ES2025", "DOM"],
/* === Output === */
"outDir": "dist",
"rootDir": "src",
"sourceMap": true,
"declaration": true, // sinh .d.ts cho lib
/* === Build perf === */
"incremental": true,
"tsBuildInfoFile": ".tscache/.tsbuildinfo",
/* === Quality of life === */
"esModuleInterop": true, // import từ CJS như ESM
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true, // skip check .d.ts node_modules
"resolveJsonModule": true,
"isolatedModules": true, // ép tương thích bundler
/* === TS 6.0+ defaults hữu ích === */
"noUncheckedSideEffectImports": true, // mặc định true — bắt side-effect import
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
"Từ TypeScript 6.0,
strict: trueđã trở thành mặc định — project mới tự động có strict mà không cần khai báo tường minh (dù vẫn nên để cho rõ ràng). Strict bật 8 flag:noImplicitAny,strictNullChecks,strictFunctionTypes,strictBindCallApply,strictPropertyInitialization,alwaysStrict,useUnknownInCatchVariables,noImplicitThis.Quan trọng nhất là
strictNullChecks— phân biệtstringvàstring | undefinedrõ ràng, ngănCannot read property of undefined. Ngoài ra, TS 6.0/7.0 còn thêm:noUncheckedSideEffectImports: true,types: [](không auto-discover @types/*),stableTypeOrdering: true(không thể tắt). Module mặc định làesnext, target mặc định theo ES stable hiện tại. Project cũ migrate dần dần."
Các flag hay được hỏi
| Flag | Tác dụng |
|---|---|
noImplicitAny | Báo lỗi nếu type không xác định được → ép phải khai báo |
strictNullChecks | null và undefined không assignable vào type khác |
noUnusedLocals | Cảnh báo biến local không dùng |
noUnusedParameters | Cảnh báo parameter không dùng |
exactOptionalPropertyTypes | {x?: string} không cho gán {x: undefined} — phân biệt thiếu key vs có key undefined |
noUncheckedIndexedAccess | arr[i] trả T | undefined thay vì T — bắt out-of-bound |
skipLibCheck | Skip check .d.ts của lib (nhanh hơn) — recommend true |
isolatedModules | Mỗi file phải compile độc lập — bắt buộc với esbuild, swc |
noUncheckedSideEffectImports | Bắt lỗi import module chỉ để lấy side effect mà không dùng export |
stableTypeOrdering | Type ordering ổn định giữa các lần build — mặc định true, không thể tắt từ TS 6.0 |
5. Compile vs Type-check với tsgo
# === tsgo (Go compiler) ===
# Compile + emit JS (nhanh hơn 8-13× so với tsc)
tsgo
# Chỉ type-check, không emit
tsgo --noEmit
# Watch mode với Go-native file watcher (dùng @parcel/watcher port)
tsgo --watch
# Parallel type-checking — 8 worker threads
tsgo --checkers 8
# Monorepo build với parallel builders
tsgo --build --builders 4
# Single-thread mode (debug/profile)
tsgo --singleThreaded
# === Bundler ===
# Bundle web app với Vite
vite build
# Bundle lib/CLI với esbuild
esbuild src/index.ts --bundle --outfile=dist/index.js
- App web: Vite cho dev/bundle +
tsgo --noEmitở CI để type-check (nhanh hơn tsc ở CI). - Lib npm:
tsgođể emit JS +.d.ts. Hoặc tsup/unbuild (lưu ý: tsup cần--no-dtsvới tsgo). - CLI: tsx cho dev, esbuild/tsup cho bundle.
- Test/Lint: Giữ TS 6 (
tsc6) cho ts-jest, typescript-eslint (chưa hỗ trợ tsgo).
6. Editor setup
VS Code với TypeScript Native Preview
Cài extension "TypeScript (Native) Preview" từ VS Code marketplace:
ext install ms-vscode.vscode-typescript-next
Extension này dùng tsgo làm language server, cho trải nghiệm:
- Auto-import semantic — import chính xác hơn.
- Semantic highlighting — màu sắc dựa trên type, không chỉ syntax.
- Import sorting tự động.
- Unused import removal tự động.
- Multi-threaded LSP — không lag khi mở project lớn.
// .vscode/settings.json
{
// Nếu dùng Native Preview extension, nó tự chọn tsgo làm language server
// Nếu dùng TS 6, giữ:
"typescript.tsdk": "node_modules/typescript/lib",
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit",
"source.fixAll": "explicit"
},
"typescript.preferences.importModuleSpecifier": "non-relative"
}
JetBrains
JetBrains (WebStorm, IntelliJ) chưa hỗ trợ tsgo (theo dõi issue WEB-72048). Tạm thời dùng TS 6 language service trong IDE, tsgo cho build.
Tool compatibility
| Tool | Status | Ghi chú |
|---|---|---|
| Vite 6+ | ✅ Works natively | Dùng tsgo làm type checker |
| Webpack | ✅ ts-loader v10+ hoặc esbuild-loader | ts-loader v10 hỗ trợ tsgo |
tsup (không --dts) | ✅ Works | --dts cần programmatic API → giữ TS 6 |
| VS Code Native Preview | ✅ Works | Extension chính thức từ Microsoft |
| ts-node | ❌ Chưa tương thích | Cần programmatic API → TS 7.1 |
| ts-jest | ❌ Chưa tương thích | Giữ TS 6 cho test |
| ts-morph | ❌ Chưa tương thích | Cần programmatic API |
| typescript-eslint | ❌ Chưa tương thích | Giữ TS 6 cho linting |
Lint + format
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
npm install -D prettier
// package.json scripts
{
"scripts": {
"build": "tsgo",
"type-check": "tsgo --noEmit",
"type-check:ci": "tsgo --noEmit --checkers 4",
"lint": "npx tsc6 --noEmit && eslint . --ext .ts,.tsx",
"format": "prettier --write \"src/**/*.{ts,tsx,json}\""
}
}
7. Compile target — chọn gì?
target | JS version | Khi nào |
|---|---|---|
ESNext | Theo TS version | Lib publish — bundler/user tự transpile |
ES2025 | Node 24+, modern browser 2026 | App mới, control môi trường |
ES2022 | Node 18+, evergreen browser | Đa số project |
ES2020 | Rất rộng | Web app conservative |
target: "es5" đã bị xóa hoàn toàn từ TS 6.0 — sẽ throw error nếu cố dùng. Nếu thực sự cần ES5 output, compile TS → JS hiện đại trước, sau đó dùng Babel hoặc swc để downlevel.8. Module system — ESM vs CommonJS
// ESM (chuẩn 2026 — mặc định từ TS 6.0)
import { foo } from './foo.js'; // ⚠️ ESM phải có .js extension
export const bar = 1;
// CommonJS (legacy — vẫn hỗ trợ trong tsgo)
const { foo } = require('./foo');
module.exports = { bar: 1 };
import từ file local phải kèm .js mặc dù file thực tế là .ts. TS không tự thêm cho bạn:// ❌
import { foo } from './foo';
import { foo } from './foo.ts';
// ✅
import { foo } from './foo.js'; // TS resolve đúng vì biết .ts ↔ .js mapping
Node.js package.json
{
"type": "module", // bật ESM cho .js
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
}
module: "esnext" là mặc định, ESM là con đường chính. CommonJS vẫn được hỗ trợ qua module: "node16" hoặc module: "nodenext" nếu cần, nhưng AMD/UMD/SystemJS đã bị xóa hoàn toàn.9. Đặc thù TypeScript nên nhớ ngay
- Type chỉ tồn tại compile-time — không thể
instanceof MyInterfaceở runtime. - Structural typing — 2 type "compatible" nếu cấu trúc khớp, không cần explicit implement.
- Generic erasure — generic biến mất khi compile (khác C#).
anyvsunknownvsnever— sẽ học chi tiết ở phần Type System.as(type assertion) ≠ cast runtime — chỉ tell compiler tin bạn.- Compiler Go (
tsgo) — từ TS 7.0, dùngtsgocho build/type-check (nhanh hơn 8-13×), giữtsc6cho tooling (lint, test, programmatic API). strictlà mặc định — không cần khai báo nhưng nên để rõ ràng trong tsconfig.module: "esnext"là mặc định,targettheo ES stable — ES5, AMD, UMD, SystemJS đã bị xóa.types: []là mặc định — không còn auto-discover@types/*, phải khai báo tường minh trongtypesarray.baseUrlđã bị xóa — dùng explicitpathsthay thế.