TypeScript และ tsconfig.json
บทความนี้อธิบายเกี่ยวกับ TypeScript และ tsconfig.json
เริ่มจากบทบาทพื้นฐานของ TypeScript เราจะอธิบายด้วยตัวอย่างเฉพาะว่า tsconfig.json ทำงานอย่างไรในโปรเจกต์
YouTube Video
TypeScript และ tsconfig.json
TypeScript คือ 'JavaScript ที่มีระบบชนิดข้อมูล (types)' อย่างไรก็ตาม การใช้ TypeScript ให้เกิดประโยชน์สูงสุดในโปรเจกต์จริง จำเป็นต้อง เข้าใจ tsconfig.json อย่างถูกต้องและตั้งค่าด้วยจุดประสงค์ที่ชัดเจน
ทำไมเราถึงต้องใช้ TypeScript?
เหตุผลหลักที่ใช้ TypeScript คือ 'ความสามารถในการตรวจจับความผิดพลาดก่อนที่จะรันโปรแกรม'
1function add(a: number, b: number): number {
2 return a + b;
3}
4
5add(1, "2");โค้ดนี้จะไม่ทำให้เกิดข้อผิดพลาดใน JavaScript จนกว่าจะรัน แต่ใน TypeScript จะเกิด ข้อผิดพลาดทางชนิดข้อมูลตั้งแต่ระหว่างคอมไพล์
'การตรวจพบล่วงหน้า' นี้ช่วยเพิ่มประสิทธิภาพและคุณภาพในการพัฒนาอย่างมาก
TypeScript ทำงานอย่างไร?
โดยหลักการแล้ว TypeScript ไม่สามารถถูกรันได้โดยตรง คุณต้องแปลงเป็น JavaScript ด้วย tsc (TypeScript Compiler)
1npm install -D typescript
2npx tsc --init- เมื่อดำเนินการนี้จะมีการสร้าง
tsconfig.jsonซึ่งเป็น ไฟล์หลักที่กำหนดพฤติกรรมของโปรเจกต์ TypeScript
tsconfig.json มีบทบาทอย่างไร?
tsconfig.json คือไฟล์กำหนดค่าที่ระบุว่า 'ไฟล์ไหน' 'ด้วยกฎอะไร' และ 'ต้องแปลงอย่างไร' แม้จะดูซับซ้อนในตอนแรก แต่จริง ๆ แล้วมีเพียงไม่กี่การตั้งค่าที่สำคัญจริง ๆ
1{
2 "compilerOptions": {
3 "target": "ES2020",
4 "module": "ESNext",
5 "strict": true
6 }
7}- เพียงแค่การตั้งค่าเหล่านี้ คุณก็สามารถพัฒนา TypeScript ได้อย่างทันสมัยและปลอดภัย
target: กำหนดเวอร์ชันของ JavaScript ที่จะสร้างออกมา
target กำหนด เวอร์ชันหรือระดับของ JavaScript ที่จะได้จากการคอมไพล์
1"target": "ES2020"ด้วยการตั้งค่านี้ TypeScript จะสร้าง JavaScript ที่เทียบเท่า ES2020 สำหรับสภาพแวดล้อมเก่า ให้เลือก ES5; หากใช้เฉพาะสภาพแวดล้อมล่าสุด ให้เลือก ES2022 เป็นต้น
เมื่อกำหนดค่าเป็น ESNext
1"target": "ESNext"-
ESNextคือการตั้งค่าให้ สร้าง JavaScript ด้วยไวยากรณ์ล่าสุดเท่าที่เป็นไปได้ TypeScript จะไม่แปลงไวยากรณ์ แต่จะปล่อยให้ runtime environment เช่น Node.js หรือเบราว์เซอร์เป็นผู้จัดการ -
ดังนั้น
ESNextจึงเหมาะในกรณีที่รันเฉพาะบน Node.js เวอร์ชันล่าสุด หรือกรณีที่ใช้ Babel หรือ bundler แปลงโค้ดในขั้นตอนแยก แต่หาก runtime environment ไม่รองรับไวยากรณ์ล่าสุด อาจจะเกิดข้อผิดพลาดตอนรันโปรแกรมได้ จึงต้องระมัดระวัง
module: กำหนดรูปแบบโมดูล
module ใช้กำหนด รูปแบบของโมดูล
1"module": "ESNext"ESNextเป็นมาตรฐานสำหรับงาน frontend และ Node.js ยุคใหม่- เลือก
"CommonJS"เฉพาะเมื่อคุณต้องการใช้งาน CommonJS
strict: เพิ่มความปลอดภัยของชนิดข้อมูลให้สูงสุด
ตัวเลือก strict เป็น สวิตช์ที่ช่วยเพิ่มความปลอดภัยของ TypeScript สูงสุด
1"strict": true- เมื่อเปิดใช้งานจะช่วยตรวจจับชนิดข้อมูลที่ไม่ชัดเจนและข้อผิดพลาดที่อาจเกิดขึ้น
โหมด strict และ implicit any
เมื่อเปิดใช้งาน strict TypeScript จะถือว่าตัวแปรที่ไม่สามารถอนุมานชนิดข้อมูลได้เป็นข้อผิดพลาด
1function printValue(value) {
2 console.log(value);
3}- ตัวแปร
valueนี้ไม่ได้ระบุชนิดข้อมูล TypeScript จึงไม่สามารถระบุประเภทได้ จึงถูกกำหนดเป็นanyโดยปริยาย ซึ่งจะทำให้เกิดคำเตือน (หรือข้อผิดพลาด) หากเปิดใช้งานโหมดstrict
1function printValue(value: number) {
2 console.log(value);
3}- โดยการระบุชนิดข้อมูลอย่างชัดเจน TypeScript จะเข้าใจได้ว่า 'ตัวแปรนี้รองรับเฉพาะตัวเลขเท่านั้น' ใน TypeScript สิ่งที่สำคัญกว่าการละเว้น type คือ ชนิดข้อมูลถูกกำหนดชัดเจนและไม่คลุมเครือ
include/exclude: เลือกไฟล์ที่ต้องการคอมไพล์หรือไม่คอมไพล์
ใน tsconfig.json คุณสามารถกำหนด ไฟล์ที่ต้องการให้คอมไพล์ และ ไฟล์ที่ต้องการไม่ให้คอมไพล์ ได้
1{
2 "include": ["src"],
3 "exclude": ["node_modules"]
4}- ด้วยการตั้งค่าแบบนี้ ไฟล์ที่อยู่ใน
srcเท่านั้นที่ TypeScript จะจัดการ node_modulesที่ถูกระบุในexcludeจะไม่ถูกคอมไพล์ แม้จะอยู่ภายใต้ path ที่รวมอยู่ในincludeก็ตาม
outDir: กำหนดโฟลเดอร์ปลายทางสำหรับไฟล์ที่สร้าง
กำหนด outDir เพื่อควบคุมตำแหน่งไฟล์ที่ได้จากการ build
1"outDir": "dist"- ด้วยการตั้งค่านี้ไฟล์ที่คอมไพล์เสร็จทุกไฟล์จะถูกส่งไปที่โฟลเดอร์
distในการใช้งานจริง ควรแยกไฟล์ซอร์สโค้ดออกจากไฟล์ผลลัพธ์ (build)
rootDir: กำหนดโฟลเดอร์ที่เก็บซอร์สโค้ด
rootDir ใช้กำหนดว่า ไดเร็กทอรีใดคือรากของซอร์สโค้ดสำหรับ TypeScript
1"rootDir": "src"-
การตั้งค่านี้ช่วยให้ TypeScript คงโครงสร้างไดเร็กทอรีของ
srcตอนสร้างไฟล์ผลลัพธ์ เช่นsrc/index.tsจะได้ผลลัพธ์เป็นdist/index.js -
โครงสร้างของโฟลเดอร์ที่กำหนดใน
rootDirจะถูกสร้างซ้ำในoutDir
esModuleInterop: การเชื่อมต่อระหว่าง CommonJS และ ES Modules
ต่อไป มาดูตัวเลือก esModuleInterop กัน
1"esModuleInterop": true- หากเปิดใช้ คุณสามารถนำเข้าโมดูลแบบ CommonJS ด้วยไวยากรณ์
importได้อย่างปลอดภัย
1import fs from "fs";- การตั้งค่านี้ถือว่า จำเป็นมาก เมื่อใช้งานร่วมกับ Node.js
noImplicitAny: ห้ามใช้ค่าประเภท 'any' โดยไม่ได้ระบุ
การตั้งค่าเพื่อตรวจสอบชนิดข้อมูลให้รัดกุมใน tsconfig.json ก็สำคัญเช่นกัน
1"noImplicitAny": true- ด้วยการตั้งค่านี้ จะช่วยป้องกันการใช้ชนิด
anyโดยไม่ได้ตั้งใจ ช่วยให้คุณสามารถตรวจพบจุดที่ลืมระบุชนิดข้อมูลได้อย่างแม่นยำ
การตั้งค่าสำหรับตรวจหาโค้ดที่ไม่ได้ใช้งาน
ตัวเลือกสำหรับตรวจหาโค้ดที่ไม่ได้ใช้งานก็ช่วยเพิ่มความง่ายในการดูแลโค้ด
1"noUnusedLocals": true,
2"noUnusedParameters": true- ด้วยการตั้งค่านี้ ตัวแปรหรือพารามิเตอร์ที่ไม่ได้ใช้งานจะถูกแจ้งเตือนทันที
lib: กำหนด API มาตรฐานที่ใช้งานได้
lib คือการตั้งค่าที่ระบุว่า TypeScript ควรคาดหวังให้มี API อะไรบ้าง
1"lib": ["ES2020", "DOM"]- ด้วยการตั้งค่านี้ ชนิดข้อมูลต่อไปนี้จะใช้งานได้:
หากตั้งเป็น
ES2020จะสามารถใช้ฟีเจอร์ใหม่ ๆ เช่นPromise,Map, และSetได้ หากระบุDOMจะสามารถใช้ API ของเบราว์เซอร์ เช่นdocument,window, และHTMLElement
ถ้าทำงานฝั่ง frontend ให้ใส่ DOM; หากเป็นโปรเจกต์ Node.js อย่างเดียว ให้ลบ DOM ออกเพื่อ ป้องกันไม่ให้ชนิด global ที่ไม่จำเป็นเข้ามา
moduleResolution: กำหนดวิธีการค้นหาโมดูล
moduleResolution ใช้ระบุว่า TypeScript จะค้นหาและจับคู๋โมดูลจาก import อย่างไร
1"moduleResolution": "Node"โดยหลัก ๆ จะมีตัวเลือก 2 แบบดังนี้:
- หากตั้งเป็น
Nodeจะใช้กติกาการค้นหาโมดูลแบบ Node.js Classicเป็นวิธีเก่าเหมาะกับ TypeScript โดยเฉพาะ แต่ปัจจุบันนี้ไม่ค่อยใช้งานแล้ว
สำหรับโปรเจกต์ที่ใช้ Node.js หรือ bundler แนะนำให้ ระบุ Node โดยตรง
ตัวอย่าง tsconfig.json ที่เรียบง่ายสำหรับใช้งานจริง
จากที่กล่าวมาทั้งหมด tsconfig.json ที่เหมาะกับการใช้งานจริงแบบเรียบง่าย จะมีหน้าตาดังนี้:
1{
2 "compilerOptions": {
3 "target": "ES2020",
4 "module": "ESNext",
5 "moduleResolution": "Node",
6 "lib": ["ES2020", "DOM"],
7 "strict": true,
8 "rootDir": "src",
9 "outDir": "dist",
10 "esModuleInterop": true,
11 "noImplicitAny": true,
12 "noUnusedLocals": true,
13 "noUnusedParameters": true
14 },
15 "include": ["src"]
16}การตั้งค่านี้เหมาะสำหรับโปรเจกต์ทั้งฝั่ง frontend และ Node.js อย่างปลอดภัย
สรุป: tsconfig.json คือ 'คู่มือกฎระเบียบของโปรเจกต์'
tsconfig.json ไม่ใช่แค่ไฟล์สำหรับตั้งค่า แต่เป็น 'คู่มือกฎ' ที่มีผลกับโปรเจกต์ทั้งหมด ด้วย tsconfig.json จะช่วยกำหนดนโยบายสำคัญ ๆ ต่อไปนี้อย่างชัดเจน:
- ระดับความปลอดภัยของชนิดข้อมูล
- มาตรฐานการเขียนโค้ดของทีมคุณ
- การป้องกันบั๊กในอนาคต
หากเข้าใจ tsconfig.json คุณจะสามารถ ไม่เพียงแค่เขียนโค้ด TypeScript ได้ แต่สามารถออกแบบโปรเจกต์ให้ใช้ TypeScript ได้อย่างปลอดภัยอีกด้วย
คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย