Variables & Types
Variables: แนวคิดที่คุ้นเคย แต่กฎต่างกัน
หัวข้อที่มีชื่อว่า “Variables: แนวคิดที่คุ้นเคย แต่กฎต่างกัน”ใน TypeScript คุณประกาศตัวแปรด้วย let หรือ const จะใส่ annotation บอก type ด้วยหรือไม่ก็ได้ แล้วคอมไพเลอร์จะคุม type นั้นไปตลอดอายุของตัวแปร ส่วนใน Python แค่เขียนชื่อแล้ว assign ค่าลงไป ไม่มีคีย์เวิร์ด ไม่มีคอมไพเลอร์ ตัวแปรเกิดขึ้นตั้งแต่บรรทัดนั้น และ type ก็คือสิ่งที่คุณ assign ลงไปนั่นเอง
จุดต่างสำคัญคือ type system ของ TypeScript ทำงานตอน compile-time แล้วหายไปตอน runtime ส่วน type hints ของ Python เป็นแค่ annotation ที่ใส่หรือไม่ใส่ก็ได้ interpreter ไม่บังคับตามให้ ต้องพึ่ง tool ภายนอกอย่าง mypy มาตรวจแยกอีกที
การประกาศตัวแปร
หัวข้อที่มีชื่อว่า “การประกาศตัวแปร”// TypeScriptlet age: number = 30;let name: string = "Alice";const PI: number = 3.14159;let isActive: boolean = true;
// Inferred type — TS figures it outlet score = 100; // inferred as number# Pythonage: int = 30name: str = "Alice"PI: float = 3.14159is_active: bool = True
# No annotation needed — works the samescore = 100 # Python infers nothing; it is just an intสังเกตความต่างของสไตล์:
- ไม่มีคีย์เวิร์ด
letหรือconst— ตัว assignment นั่นแหละคือการประกาศ - ใช้
snake_caseสำหรับชื่อตัวแปร (ไม่ใช่camelCase) True/Falseขึ้นต้นด้วยตัวพิมพ์ใหญ่ (ไม่ใช่ตัวพิมพ์เล็กแบบ JS/TS)
ค่าคงที่ตามธรรมเนียม: UPPER_CASE
หัวข้อที่มีชื่อว่า “ค่าคงที่ตามธรรมเนียม: UPPER_CASE”Python ไม่มีคีย์เวิร์ด const ธรรมเนียมของชุมชนคือตั้งชื่อค่าคงที่เป็น UPPER_SNAKE_CASE ซึ่งไม่ได้ห้าม assign ทับจริง ๆ แต่เป็นสัญญาณบอกเพื่อนร่วมทีมว่าอย่าไปแตะ
// TypeScript — enforced at compile timeconst MAX_RETRIES: number = 3;const API_BASE = "https://api.example.com";
// MAX_RETRIES = 5; // TS error: cannot assign to const# Python — convention only, NOT enforcedMAX_RETRIES: int = 3API_BASE: str = "https://api.example.com"
# Technically legal (but don't do this):# MAX_RETRIES = 5 # no error, just bad styleDynamic typing ในการใช้งานจริง
หัวข้อที่มีชื่อว่า “Dynamic typing ในการใช้งานจริง”ตัวแปรใน Python ไม่ได้ล็อกอยู่กับ type แรกที่ assign ลงไป เพราะเป็นแค่ชื่อที่ชี้ไปยัง object คุณ rebind ไปเป็น type ไหนตอนไหนก็ได้ ฝั่ง TypeScript จะตีตกตั้งแต่ compile-time ส่วน Python ปล่อยผ่าน
// TypeScriptlet value: string | number = "hello";value = 42; // OK — union type// value = true; // Error — not in the union# Pythonvalue = "hello"print(type(value)) # <class 'str'>
value = 42print(type(value)) # <class 'int'>
value = [1, 2, 3]print(type(value)) # <class 'list'>การ assign หลายค่าพร้อมกัน
หัวข้อที่มีชื่อว่า “การ assign หลายค่าพร้อมกัน”Python unpack หลายค่าในบรรทัดเดียวได้ ที่เป็นท่าที่ TypeScript developer คุ้นอยู่แล้วจาก array destructuring
// TypeScript destructuringconst [x, y, z] = [1, 2, 3];const { name, age } = { name: "Alice", age: 30 };# Python tuple unpackingx, y, z = 1, 2, 3print(x, y, z) # 1 2 3
# Works with any iterablefirst, *rest = [10, 20, 30, 40]print(first, rest) # 10 [20, 30, 40]f-string และ t-string
หัวข้อที่มีชื่อว่า “f-string และ t-string”f-string แทนค่าให้ทันทีแล้วคืน str ที่เสร็จแล้วมาให้ ส่วน Python 3.14 เพิ่ม t-string (PEP 750) เข้ามา — syntax เหมือนกันแต่ขึ้นต้นด้วย t และผลลัพธ์เป็น object Template ที่ยังแยกส่วนข้อความคงที่กับค่าที่แทรกเข้าไปออกจากกัน TypeScript มีการแยกแบบนี้มานานแล้ว คือ template literal ธรรมดาเทียบกับ tagged template
// TypeScriptconst name = "O'Brien";
// Template literal — one finished stringconst msg = `Hello, ${name}`;
// Tagged template — the tag sees the piecesfunction sql(strings: TemplateStringsArray, ...values: unknown[]) { return { text: strings.join("?"), values };}const query = sql`SELECT * FROM users WHERE name = ${name}`;# Python 3.14name = "O'Brien"
# f-string — one finished stringmsg = f"Hello, {name}"
# t-string — a Template, not a strquery = t"SELECT * FROM users WHERE name = {name}"print(type(query).__name__) # Templateprint(query.strings) # ('SELECT * FROM users WHERE name = ', '')print([i.value for i in query.interpolations]) # ["O'Brien"]เหตุผลที่มันสำคัญก็เหมือนกับที่ tagged template สำคัญใน TypeScript คือ f-string เชื่อมค่าเข้าไปในข้อความเลย ถ้าใน name มี quote ก็กลายเป็น SQL injection ทันที ส่วน t-string ส่งข้อความคงที่กับค่าแยกกันให้ไลบรารี ไลบรารีจึง bind เป็น parameter ได้ หลักจำง่าย ๆ: ข้อความที่แค่ print ใช้ f-string ส่วนอะไรที่ปลายทางมี parser อ่านต่อ — SQL, HTML, shell — ใช้ t-string
ลองเล่นดู
หัวข้อที่มีชื่อว่า “ลองเล่นดู”# Experiment with Python variablesage: int = 30name: str = "Alice"PI: float = 3.14159is_active: bool = True
print(f"name={name}, age={age}, PI={PI}, is_active={is_active}")
# Dynamic reassignment — Python allows thisage = "thirty"print(f"age is now: {age} (type: {type(age).__name__})")
# Multiple assignmentx, y, z = 1, 2, 3print(f"x={x}, y={y}, z={z}")
# Star unpackingfirst, *rest = [10, 20, 30, 40]print(f"first={first}, rest={rest}")Loading Python runtime (first run only)…