TypeScript และ tsconfig.json

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 ด้วย

YouTube Video