Static Type Checking — mypy
“TypeScript moment” ของ Python
หัวข้อที่มีชื่อว่า ““TypeScript moment” ของ Python”ตอนเริ่มเขียน TypeScript ใหม่ ๆ คุณคงเคยเจอวินาทีที่ compiler จับ bug จริงได้ตั้งแต่ยังไม่ได้รันโค้ด type hints ของ Python ให้ประโยชน์แบบเดียวกันได้ ต่างกันตรงที่ interpreter ไม่เคยตรวจให้เลย งานตรวจจึงตกเป็นของ static analysis tool แยกต่างหากอย่าง mypy
มอง mypy เป็น tsc --noEmit เวอร์ชัน Python ได้เลย คืออ่าน annotation ของคุณแล้วรายงาน type error ออกมา โดยไม่ต้องรันหรือ compile อะไรทั้งสิ้น
การติดตั้งและรัน
หัวข้อที่มีชื่อว่า “การติดตั้งและรัน”รันในเทอร์มินัลของคุณ:
pip install mypy# หรือ:uv add --dev mypy
# ตรวจสอบไฟล์เดียวmypy src/main.py
# ตรวจสอบทั้ง packagemypy src/
# โหมด strict (เทียบกับ tsconfig "strict: true")mypy --strict src/การ annotate Python เทียบกับ TypeScript
หัวข้อที่มีชื่อว่า “การ annotate Python เทียบกับ TypeScript”// TypeScript — types enforced by compilerfunction greet(name: string): string { return `Hello, ${name}!`;}
function add(a: number, b: number): number { return a + b;}
// Genericfunction first<T>(arr: T[]): T | undefined { return arr[0];}# Python — types checked by mypy, ignored by interpreterdef greet(name: str) -> str: return f"Hello, {name}!"
def add(a: int, b: int) -> int: return a + b
# Generic (Python 3.12+ syntax)def first[T](arr: list[T]) -> T | None: return arr[0] if arr else NoneType annotations ที่ใช้บ่อย
หัวข้อที่มีชื่อว่า “Type annotations ที่ใช้บ่อย”// TypeScript common typesconst names: string[] = ["Alice", "Bob"];const scores: Map<string, number> = new Map();const user: { name: string; age: number } | null = null;
// Optional parameterfunction find(id: number, strict?: boolean): string | null { return null;}
// Uniontype Result = { ok: true; value: string } | { ok: false; error: string };# Python 3.10+ common typesfrom typing import Optional
names: list[str] = ["Alice", "Bob"]scores: dict[str, int] = {}user: dict[str, str | int] | None = None
# Optional parameter (None default = Optional)def find(id: int, strict: bool = False) -> str | None: return None
# TypedDict สำหรับ dict ที่มีโครงสร้างชัดเจนfrom typing import TypedDict
class OkResult(TypedDict): ok: bool value: strลองด้วยตัวเอง — type hints ในการทำงานจริง
หัวข้อที่มีชื่อว่า “ลองด้วยตัวเอง — type hints ในการทำงานจริง”from typing import Optional
def double(x: int) -> int: return x * 2
def greet(name: str) -> str: return f"Hello, {name}!"
# สิ่งเหล่านี้ทำงานได้ปกติprint(double(5))print(greet("Alice"))
# Type hints ไม่หยุดสิ่งนี้ที่ runtime:result = double("oops") # mypy จะ flag แต่ Python รันได้print(result) # prints 'oopsoops' — string * 2 ทำซ้ำ!Loading Python runtime (first run only)…
การตั้งค่า mypy เทียบกับ tsconfig
หัวข้อที่มีชื่อว่า “การตั้งค่า mypy เทียบกับ tsconfig”// tsconfig.json{ "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true, "target": "ES2022", "module": "NodeNext" }}# pyproject.toml [tool.mypy] section[tool.mypy]python_version = "3.11"strict = true # เปิดใช้ strict checks ทั้งหมดwarn_return_any = truedisallow_untyped_defs = trueignore_missing_imports = true # สำหรับ third-party libs ที่ไม่มี type