TypeScript

Giới thiệu và Cài đặt TypeScript 7.0 RC

TypeScript 7.0 RC (June 2026) — Project Corsa, compiler Go 10× nhanh hơn, tsgo CLI, ESM default, strict default. Cài đặt + tsconfig essentials.

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.

Vì sao TypeScript phổ biến đến vậy?
  • 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

ProjectTS 6 (tsc)TS 7 (tsgo)Nhanh hơn
VS Code (1.5M dòng)77.8s7.5s10.4×
Sentry133s16s8.2×
TypeORM17.5s1.3s13.5×
Playwright11.1s1.1s10.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)

SettingGiá trị mặc địnhGhi chú
stricttrueKhông cần khai báo nữa!
module"esnext"ESM là first-class
targetES stable hiện tạiKhông còn ES5!
types[]Không auto-discover @types/*
noUncheckedSideEffectImportstrueBắt lỗi side-effect import
stableTypeOrderingtrueKhông thể tắt — type ordering ổn định
rootDirThư mục chứa tsconfigKhô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óaThay thế / Ghi chú
target: "es5"Dùng Babel hoặc swc sau khi TS compile
downlevelIterationKhô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
baseUrlDùng explicit paths
Import assertions (assert)Phải dùng with keyword
preserveConstEnumsKhông còn được hỗ trợ
JSDoc @enum trong .jsKhô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+
2026 trend: Node.js hỗ trợ type stripping native từ Node 23+. Không cần ts-node/tsx để run nhanh. Build thật và type-check vẫn dùng 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

  1. Upgrade lên TS 6.0 trước — tất cả deprecation sẽ hiện warning.
  2. Fix tất cả warning. Kiểm tra target: es5, baseUrl, module: amd, import assertions, v.v.
  3. Cài tsgo song song với tsc:
npm install -D @typescript/native-preview
  1. Chạy cả 2 trong CI đến khi output khớp:
npx tsc --noEmit && npx tsgo --noEmit
  1. 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
--declarationMapChưa hỗ trợ trong tsgo
ts-node / ts-jestKhông tương thích với tsgo — giữ TS 6 để chạy test/script
ts-morphChưa tương thích — cần programmatic API
typescript-eslintGiữ TS 6 cho linting — chưa hỗ trợ tsgo
Chiến lược khuyên dùng: Dùng tsgo cho build và type-check (nhanh hơn nhiều), TS 6 cho tooling (lint, test, programmatic API). 2 compiler có thể cùng tồn tại trong 1 project.

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"]
}
Câu PV cốt lõi:"strict mode trong tsconfig thay đổi thế nào từ TS 6.0?"

"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ệt stringstring | undefined rõ ràng, ngăn Cannot 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

FlagTác dụng
noImplicitAnyBáo lỗi nếu type không xác định được → ép phải khai báo
strictNullChecksnullundefined không assignable vào type khác
noUnusedLocalsCảnh báo biến local không dùng
noUnusedParametersCả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
noUncheckedIndexedAccessarr[i] trả T | undefined thay vì T — bắt out-of-bound
skipLibCheckSkip check .d.ts của lib (nhanh hơn) — recommend true
isolatedModulesMỗi file phải compile độc lập — bắt buộc với esbuild, swc
noUncheckedSideEffectImportsBắt lỗi import module chỉ để lấy side effect mà không dùng export
stableTypeOrderingType 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
Workflow phổ biến 2026:
  • 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-dts vớ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

ToolStatusGhi chú
Vite 6+✅ Works nativelyDùng tsgo làm type checker
Webpack✅ ts-loader v10+ hoặc esbuild-loaderts-loader v10 hỗ trợ tsgo
tsup (không --dts)✅ Works--dts cần programmatic API → giữ TS 6
VS Code Native Preview✅ WorksExtension chính thức từ Microsoft
ts-node❌ Chưa tương thíchCần programmatic API → TS 7.1
ts-jest❌ Chưa tương thíchGiữ TS 6 cho test
ts-morph❌ Chưa tương thíchCần programmatic API
typescript-eslint❌ Chưa tương thíchGiữ 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ì?

targetJS versionKhi nào
ESNextTheo TS versionLib publish — bundler/user tự transpile
ES2025Node 24+, modern browser 2026App mới, control môi trường
ES2022Node 18+, evergreen browserĐa số project
ES2020Rất rộngWeb 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 };
Bẫy ESM: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"
    }
  }
}
Từ TS 7.0 với 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#).
  • any vs unknown vs never — 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ùng tsgo cho build/type-check (nhanh hơn 8-13×), giữ tsc6 cho tooling (lint, test, programmatic API).
  • strict là 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, target theo 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 trong types array.
  • baseUrl đã bị xóa — dùng explicit paths thay thế.

© 2026 .NET Fresher Guide. All rights reserved.

Về Trang Web

Hướng dẫn toàn diện để chuẩn bị phỏng vấn vị trí .NET Fresher với nội dung từ lý thuyết đến thực hành.