Skip to content

Nhập môn Type System

Mở đầu

Tại sao "1" + 1 trong JavaScript = "11", trong Python lại error? Đây là type system hoạt động. Type system là "luật giao thông" của ngôn ngữ — quyết data dùng thế nào, operation với cái nào, check legal lúc nào. Hiểu type system = hiểu "tính cách" khác nhau của ngôn ngữ.

Bạn sẽ học:

  • Năng lực phân loại: nắm 4 quadrant static/dynamic + strong/weak
  • Diagnose vấn đề: gặp TypeError định vị nhanh nguyên nhân
  • Chọn ngôn ngữ: hiểu sao TypeScript phù hợp project lớn, Python phù hợp prototype
  • Type inference: hiểu ngôn ngữ hiện đại cân bằng đơn giản + an toàn
  • Practice awareness: thói quen code type-safe
ChươngNội dung
1Type system là gì
2Static vs Dynamic
3Strong vs Weak
4Type inference
5Generics
6Type safety thực chiến
74 quadrant ngôn ngữ

0. Toàn cảnh: type là "CMND" của data

Trong đời thực, bạn không nhét sách vào cốc cafe — vì chúng là loại khác. Programming tương tự: number, string, boolean, array... mỗi loại có "identity" riêng, quyết tham gia operation nào.

Type system là hệ rule ngôn ngữ quản lý "identity" này. Trả lời 2 câu hỏi:

2 câu hỏi core

  • Khi nào check? Lúc viết code (static), hay lúc chạy (dynamic)?
  • Strict thế nào? Nghiêm cấm mix (strong) hay tự convert giúp (weak)?

1. Type system: luật giao thông data

类型系统探索器静态 vs 动态 · 强类型 vs 弱类型 · 类型推断
强类型弱类型静态动态
强 + 静态
JavaRustHaskell
弱 + 静态
CC++
强 + 动态
PythonRuby
弱 + 动态
JavaScriptPHP
强 + 静态
编译期严格检查,不允许隐式转换。最安全,IDE 支持最好,但写起来相对"啰嗦"。
编译期检查无隐式转换自动补全友好重构安全
核心思想:类型系统在两个维度上做选择——何时检查(静态/动态)和是否允许隐式转换(强/弱)。没有最好的组合,只有最适合的场景。

Bản chất type system = bộ constraint rule, báo compiler/interpreter:

  • Variable lưu được value gì?
  • 2 value cộng được không?
  • Function parameter phải gì?
Tác dụngMô tảVí dụ
Chống operation illegalChặn op vô nghĩaKhông chia được string
Cung cấp doc infoType là doc tốt nhấtfunction add(a: number, b: number) rõ ngay
Hỗ trợ IDE toolAutocomplete, refactoruser. → suggest hết property
Optimize performanceCompiler biết type → sinh code nhanh hơnBiết integer → dùng integer instruction

2. Static vs Dynamic: khi nào check?

Dimension quan trọng nhất.

🔍 静态类型 vs 动态类型:实时对比

选择一段代码,观察两种类型系统的不同行为

静态类型(TypeScript)⏱ 编译时检查
let name: string = "Alice"
name = 42  // ❌ 编译错误
❌ Type "number" is not assignable to type "string"
VS
动态类型(JavaScript)⏱ 运行时检查
let name = "Alice"
name = 42  // ✅ 没问题
✅ 运行正常,name 变成了 42
💡 静态类型在你写代码时就发现错误,动态类型要等到运行时才知道。

Khác biệt core

  • Static: type variable xác định lúc compile-time, code chưa chạy đã catch type error. Đại diện: Java, TypeScript, Rust, Go
  • Dynamic: type xác định lúc run-time, cùng 1 variable có thể lưu number rồi string. Đại diện: Python, JavaScript, Ruby, PHP
DimensionStaticDynamic
Thời điểm checkCompile-timeRun-time
Phát hiện bugSớmMuộn (user thao tác mới lộ)
Linh hoạtThấpCao
IDE supportTốtYếu hơn
Speed devĐầu chậm (phải viết type)Đầu nhanh
Long-term maintainabilityCaoThấp (cần test bù)

Ví dụ thực

typescript
// TypeScript (static)
function add(a: number, b: number): number {
    return a + b;
}
add(1, "2");  // ❌ Compile error: Argument of type 'string' is not assignable to parameter of type 'number'
python
# Python (dynamic)
def add(a, b):
    return a + b

add(1, "2")  # ❌ RuntimeError: unsupported operand type(s) for +: 'int' and 'str'
# Chỉ catch khi chạy tới đây

3. Strong vs Weak: strict thế nào?

Khác biệt: khi gặp type mismatch, có auto convert không?

Khác biệt core

  • Strong: không auto convert, type mismatch = error. Python, Java, Ruby
  • Weak: tự convert giúp, có thể có behavior bất ngờ. JavaScript, PHP, C

Ví dụ

javascript
// JavaScript (weak)
"5" + 3        // "53"   — convert 3 thành "3"
"5" - 3        // 2      — convert "5" thành 5 (!)
"5" * "3"      // 15     — cả 2 convert
[] + {}        // "[object Object]"  — chaos!
true + 1       // 2
python
# Python (strong)
"5" + 3        # TypeError
"5" - 3        # TypeError
int("5") + 3   # 8 — phải convert tay

JavaScript weak typing convenient nhưng buggy. TypeScript là JavaScript với "strict mode" bật.


4. 4 quadrant ngôn ngữ

StrongWeak
StaticJava, Rust, TypeScript, Kotlin, SwiftC, C++
DynamicPython, RubyJavaScript, PHP, Perl

Trend hiện đại: Static + Strong (TypeScript, Rust, Swift, Kotlin) dominant. Production app gần như luôn dùng static để catch bug sớm.


5. Type inference

Modern static language không bắt bạn viết type mọi nơi.

typescript
// Explicit
let x: number = 5;

// Inferred — TypeScript biết x là number
let x = 5;

// Inferred từ return value
function double(n: number) { return n * 2; }
// TypeScript infer return type là number

Cân bằng: get safety + dev speed.

Rust, Swift, Go, Kotlin, TypeScript đều có powerful inference.


6. Generics: viết 1 lần, dùng cho mọi type

Tránh viết duplicate cho mỗi type:

typescript
// Without generics: 3 copies
function firstOfStrings(arr: string[]): string { return arr[0]; }
function firstOfNumbers(arr: number[]): number { return arr[0]; }
function firstOfUsers(arr: User[]): User { return arr[0]; }

// With generics: 1 function cho mọi type
function first<T>(arr: T[]): T { return arr[0]; }
first<string>(["a", "b"]);    // string
first<number>([1, 2]);         // number
first<User>([user1, user2]);   // User

Constraint:

typescript
function longerOf<T extends { length: number }>(a: T, b: T): T {
    return a.length > b.length ? a : b;
}
// Chỉ work cho type có property length

7. Type safety thực chiến

7.1 Trap phổ biến

Null/undefined:

typescript
function getLength(s: string | null): number {
    return s.length;  // ❌ s có thể null
    
    if (s) return s.length;  // ✅ narrow type
    return 0;
}

Any escape hatch:

typescript
let x: any = "hello";
x.foo.bar.baz();  // Compile OK, runtime crash
// ❌ Dùng any = bỏ type safety

Type assertion liều:

typescript
const user = response.data as User;  
// ❌ Nếu response.data không phải User → bug runtime
// ✅ Dùng type guard hoặc Zod validate

7.2 Best practice

  1. Strict mode: bật strict: true trong tsconfig.json
  2. No any: ban any, dùng unknown thay
  3. Runtime validation: dùng Zod, Yup cho external data
  4. Discriminated union: model state đúng
    typescript
    type State =
      | { status: 'loading' }
      | { status: 'success'; data: User }
      | { status: 'error'; error: string };

8. Type system trong AI/ML era

Pydantic (Python): runtime type validation + type hint

python
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int
    email: str

# Validate khi parse
user = User.parse_obj({"name": "Anna", "age": 25, "email": "a@b.com"})

LangChain, Pydantic AI: dùng pydantic schema cho LLM tool calling.

Structured output từ LLM: GPT-4, Claude support JSON schema output → kết hợp Pydantic/Zod để validate response.


9. Tổng kết

Type system = trade-off:

  • Safety: catch bug sớm
  • Speed: write code nhanh
  • Flexibility: thay đổi type dễ

Modern winner: Static + Strong + Type Inference (TypeScript, Rust, Kotlin). Best of all worlds.

2026 Update

  • TypeScript dominant cho web: chiếm >70% large project mới
  • Rust mainstream cho systems
  • Pydantic v2 stable, foundation cho FastAPI, LangChain
  • Type-driven AI: dùng schema cho LLM structured output (Zod, Pydantic)
  • Gradual typing trong Python (mypy, pyright) phổ biến
  • VN dev: học TypeScript là MUST. JavaScript thuần (no TS) đã out-of-date cho production project mới

Tài liệu