แนวปฏิบัติที่ดีที่สุดสำหรับตรรกะเงื่อนไขใน TypeScript
บทความนี้อธิบายแนวปฏิบัติที่ดีที่สุดสำหรับการใช้ตรรกะเงื่อนไขใน TypeScript
YouTube Video
แนวปฏิบัติที่ดีที่สุดสำหรับตรรกะเงื่อนไขใน TypeScript
การควบคุมประเภทด้วย Type Guards
โดยการใช้ระบบประเภทของ TypeScript และ Type Guards ภายในคำสั่ง if
คุณสามารถเพิ่มความปลอดภัยของประเภทและความสามารถในการอ่านโค้ด
1function processInput(input: string | number) {
2 if (typeof input === "string") {
3 console.log(`String input: ${input.toUpperCase()}`);
4 } else {
5 console.log(`Number input: ${input.toFixed(2)}`);
6 }
7}
การใช้ typeof
และ Type Guards อื่นๆ ช่วยให้มั่นใจว่าโค้ดภายในแต่ละบล็อกจะปลอดภัยต่อประเภทและสอดคล้องกับบริบท
หลีกเลี่ยงการซ้อนคำสั่ง if
คำสั่ง if
ที่ซ้อนลึกเกินไปจะลดความสามารถในการอ่านโค้ดและการรักษาดูแล ให้ใช้การคืนค่าก่อนหน้า (early returns), การใช้ตัวดำเนินการแบบตรรกะ หรือแยกเป็นฟังก์ชันแทน
ตัวอย่างที่ไม่ดี:
1function checkUser(user: { age?: number; isAdmin?: boolean }) {
2 if (user.age) {
3 if (user.age > 18) {
4 if (user.isAdmin) {
5 console.log("User is an adult admin.");
6 }
7 }
8 }
9}
ตัวอย่างที่ปรับปรุงแล้ว:
1function checkUser(user: { age?: number; isAdmin?: boolean }) {
2 if (!user.age || user.age <= 18 || !user.isAdmin) {
3 return;
4 }
5 console.log("User is an adult admin.");
6}
วิธีการนี้ทำให้โค้ดเรียบง่ายและทำให้ตรรกะเข้าใจได้ง่ายขึ้น
การใช้งาน Optional Chaining
เมื่อคุณตรวจสอบคุณสมบัติที่ซ้อนกัน ให้ใช้ optional chaining (?.
) เพื่อหลีกเลี่ยงเงื่อนไข if
ที่ไม่จำเป็น
กรณีที่ไม่มี Optional Chaining:
1if (user && user.profile && user.profile.email) {
2 console.log(user.profile.email);
3}
การใช้ Optional Chaining:
1if (user?.profile?.email) {
2 console.log(user.profile.email);
3}
สิ่งนี้ช่วยลดโค้ดที่ซ้ำซ้อนและปรับปรุงความสามารถในการอ่าน ที่นี่ โค้ดที่ซ้ำซ้อนหมายถึงโค้ดมาตรฐานที่ต้องใช้ซ้ำบ่อยๆ เพื่อทำภารกิจเฉพาะในโปรแกรมมิ่ง
ใช้ตัวดำเนินการตรวจสอบความเท่าเทียมแบบเข้มงวด
TypeScript รองรับการจัดประเภทอย่างเข้มงวด และการใช้ตัวดำเนินการตรวจสอบความเท่าเทียมแบบเข้มงวด (===
) หรือไม่เท่าเทียม (!==
) ช่วยป้องกันการแปลงประเภทที่ไม่คาดคิด
ตัวอย่างที่ไม่ดี:
1if (value == "123") {
2 console.log("Value is 123.");
3}
ตัวอย่างที่ปรับปรุงแล้ว:
1if (value === "123") {
2 console.log("Value is 123.");
3}
ใช้ Enums หรือประเภท Literal สำหรับเงื่อนไขที่ชัดเจน
การใช้ Enums หรือประเภท Literal ทำให้เงื่อนไขชัดเจนขึ้นและลดโอกาสของข้อผิดพลาด
1type Status = "success" | "error" | "loading";
2
3function displayMessage(status: Status) {
4 if (status === "success") {
5 console.log("Operation succeeded.");
6 } else if (status === "error") {
7 console.log("Operation failed.");
8 } else {
9 console.log("Loading...");
10 }
11}
ด้วยการกำหนดค่าที่คาดไว้ TypeScript สามารถตรวจจับประเภทและรับประกันความถูกต้อง
รวมเงื่อนไขที่คล้ายกัน
เมื่อมีหลายเงื่อนไขที่ใช้ตรรกะเดียวกัน ควรรวมไว้ด้วยกันโดยใช้ตัวดำเนินการตรรกะหรือตัวเลือก switch
ตัวอย่างที่ไม่ดี:
1if (role === "admin") {
2 grantAccess();
3}
4if (role === "superadmin") {
5 grantAccess();
6}
ตัวอย่างที่ปรับปรุงแล้ว:
1if (role === "admin" || role === "superadmin") {
2 grantAccess();
3}
อีกทางเลือกหนึ่งคือใช้ตัวเลือก switch เพื่อจัดการหลายกรณีที่ชัดเจน:
1switch (role) {
2 case "admin":
3 case "superadmin":
4 grantAccess();
5 break;
6 case "user":
7 console.log("Limited access.");
8 break;
9 default:
10 console.log("No access.");
11}
หลีกเลี่ยงการทำให้เงื่อนไขซับซ้อน
การใช้เงื่อนไขที่ซับซ้อนในคำสั่ง if จะลดความเข้าใจได้ง่ายของโค้ด แยกออกมาเป็นตัวแปรหรือฟังก์ชันที่มีความหมาย
ตัวอย่างที่ไม่ดี:
1if (user.age > 18 && user.isAdmin && user.permissions.includes("write")) {
2 console.log("User can write.");
3}
ตัวอย่างที่ปรับปรุงแล้ว:
1const isAdultAdminWithWriteAccess =
2 user.age > 18 && user.isAdmin && user.permissions.includes("write");
3
4if (isAdultAdminWithWriteAccess) {
5 console.log("User can write.");
6}
การตั้งชื่อเงื่อนไขช่วยปรับปรุงความชัดเจนและทำให้โค้ดสามารถบรรยายตัวเองได้
ใช้ตัวดำเนินการ ternary สำหรับเงื่อนไขงง่าย
สำหรับเงื่อนไขง่าย ๆ การใช้ตัวดำเนินการ ternary ช่วยให้โค้ดกระชับ
ตัวอย่าง:
1const message = isLoggedIn ? "Welcome back!" : "Please log in.";
2console.log(message);
อย่างไรก็ตาม ควรหลีกเลี่ยงการใช้ตัวดำเนินการ ternary กับเงื่อนไขที่ซับซ้อนเพราะจะลดความเข้าใจได้ง่าย
แทนที่เงื่อนไขแบบกิ่งก้านด้วยอาเรย์หรือแมป
เมื่อเงื่อนไขเป็นเพียงการแมปค่าต่างๆ การใช้อาเรย์หรือแมปสามารถปรับปรุงความอ่านง่ายและความสามารถในการบำรุงรักษาโค้ดได้เมื่อเทียบกับข้อความ switch
หรือบล็อค if-else
ที่ซับซ้อน ใน TypeScript คุณสามารถใช้ข้อมูลชนิด (types) เพื่อทำให้การใช้งานปลอดภัยมากขึ้น
ตัวอย่างที่ไม่ดี:
1function getDayName(day: number): string {
2 switch (day) {
3 case 0:
4 return "Sunday";
5 case 1:
6 return "Monday";
7 case 2:
8 return "Tuesday";
9 case 3:
10 return "Wednesday";
11 case 4:
12 return "Thursday";
13 case 5:
14 return "Friday";
15 case 6:
16 return "Saturday";
17 default:
18 return "Invalid day";
19 }
20}
ตัวอย่างที่ปรับปรุงแล้ว: การใช้อาเรย์
1function getDayName(day: number): string {
2 const days = [
3 "Sunday",
4 "Monday",
5 "Tuesday",
6 "Wednesday",
7 "Thursday",
8 "Friday",
9 "Saturday"
10 ];
11 return days[day] ?? "Invalid day";
12}
ตัวอย่างที่ปรับปรุงแล้ว: การใช้แมป
1function getDayName(day: number): string {
2 const dayMap = new Map<number, string>([
3 [0, "Sunday"],
4 [1, "Monday"],
5 [2, "Tuesday"],
6 [3, "Wednesday"],
7 [4, "Thursday"],
8 [5, "Friday"],
9 [6, "Saturday"]
10 ]);
11 return dayMap.get(day) ?? "Invalid day";
12}
สรุป
ด้วยการปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดเหล่านี้ คุณสามารถทำให้คำสั่ง if ใน TypeScript ชัดเจน มีประสิทธิภาพ และดูแลรักษาได้ง่าย ด้วยการใช้คุณสมบัติต่างๆ ของ TypeScript เช่น การตรวจสอบชนิดข้อมูล (type guards), optional chaining และ enums คุณสามารถปรับปรุงความชัดเจนและความแข็งแรงของโค้ดได้ ด้วยการปฏิบัติตามวิธีที่ดีที่สุด คุณสามารถทำให้เงื่อนไขกระชับและชัดเจน ส่งผลให้โค้ดเข้าใจและดูแลรักษาได้ง่ายขึ้น
คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย