ลองเขียนเว็บง่าย ๆ ด้วย TypeScript
เรียนทฤษฎีกันมาเยอะแล้ว ลองมาเขียนเว็บแบบง่ายๆ ด้วย TypeScript กันดีกว่า!
โดยเราจะใช้ CodeSandbox ในการเซ็ตอัปโปรเจกต์ คลิกที่นี่เลย
ถ้าลิงก์ไม่เสีย เราจะเห็น Editor หน้าตาประมาณนี้ ซึ่งมีโค้ด TypeScript index.ts
ที่ทำการ Render หน้าเว็บให้แบบโล่งๆ โค้ดที่มีอยู่แล้วให้ทำการลบไปได้เลย เราจะมาลองเขียน TypeScript และเรียนรู้ไปด้วยว่า มันต่างกับ JavaScript ยังไงบ้าง
เว็บที่เราจะเขียนจะใช้การเรียก API มาแล้วแสดงผลเป็นข้อมูล User โดยในที่นี้เราจะใช้บริการของ Randomuser.me เพื่อคืนรายซื่อ User มาแบบสุ่ม และใช้ฟังก์ชั่น fetch
ในการเรียก
เมื่อเราลองพิมพ์ fetch(
ลงใป ตัว Editor จะแนะนำเราแบบคร่าวๆ ว่าต้องการอากิวเมนต์กี่ตัว และแต่ละตัวมี Type อะไรบ้าง (Feature นี้เรียกว่า Intellisense)
จากภาพ fetch
จะรับ Argument ตัวแรกเรียกว่า input
ที่มีชนิดเป็น RequestInfo
และตัวที่สองเรียกว่า init
เป็น RequestInit
หรือ undefined
(แปลว่าตัวที่สองเราจะไม่ใส่ก็ได้) และมีการคืนค่าเป็น Promise<Response>
ต่อมาเราจะใส่ input
ให้เป็น URL ของ API ที่เราต้องการใช้ คือ https://randomuser.me/api
เนื่องจาก fetch
นั้นคืนค่าเป็น Promise<Response>
เราต้องทำการรับด้วย .then
แล้วภายในจะเป็นค่าที่มีชนิดเป็น Response
หรือจะใช้ Syntax แบบ async/await
ก็ได้
ในที่นี้เพื่อความง่ายเราจะใช้แบบ Promise ไปก่อน โดยทำการแปลงค่าResponse
ที่ได้มาเป็น Object ด้วย .json()
เนื่องจาก API ที่เราทำการยิงไปนั้นคืนค่าเป็น JSON ต่อจากนั้นเราจะ Chain ด้วย .then()
อีกครั้งเพื่อทดลอง Log ข้อมูลออกมา
ใน Editor ให้กดที่ปุ่ม Console เพื่อดูค่าที่ Log ไว้
จะเห็นว่า ข้อมูลของ console.log(res)
เป็น Object ที่มีรูปร่างแบบนี้
แต่เมื่อเราลองไปชี้ที่ res
ตัวล่างกลับพบว่า มันมี Type เป็น any
เฉยเลย
สาเหตุก็คือ ตัว .json()
นั้นมีแค่หน้าที่แปลงข้อมูลเท่านั้น ไม่ได้รู้ล่วงหน้าว่าเราจะ Fetch ข้อมูลแบบไหนมา จึงทำให้มันกลายเป็น any
ในท้ายที่สุด แปลว่าหลังจากนี้เราจะเรียกฟังก์ชั่นหรือทำอะไรกับ res
ก็จะไม่ขึ้น Type Error เลย
การที่จะทำให้ res
กลับมามี Type อีกครั้ง ทำได้ด้วยการแปลงค่า โดยเรารู้อยู่แล้วว่าหน้าตาของข้อมูลจะเป็นประมาณไหน ให้สร้าง Interface หรือ Type ขึ้นมาจากข้อมูลนั้นได้เลย
เมื่อเราทำให้ res
มี Type ถูกต้องแล้ว Intellisense ก็จะกลับใช้งานได้อีกครั้ง เพราะไม่ได้เป็น any
แล้ว
คราวนี้เรามาลองทำให้พิมพ์ User ออกมา 5 คนดู โดยแก้ API URL นิดหน่อย แล้วเขียนฟังก์ชั่นมารับค่าไปแสดงผลทางเว็บ แนะนำให้ลองพิมพ์ตามแทนที่จะ Copy-Paste เพื่อให้เห็นว่า TypeScript สามารถช่วยเราในการพิมพ์โค้ดได้เยอะมากๆ ต่างจาก JavaScript ที่เราอาจต้อง console.log
เพื่อดีบั๊กค่าตัวแปรอยู่เรื่อยๆ
เมื่อทำเสร็จแล้ว กดดูที่ Browser จะเห็นว่ามีชื่อที่พิมพ์ออกมาแล้ว
Improvements
โค้ดของเราอาจทำงานได้ตามต้องการแล้ว แต่ยังมีบางจุดที่สามารถจัดการให้เรียบร้อยขึ้นได้ ดังนี้
1. Refactor Type
โดยทั่วไปแล้วเราจะไม่สร้าง Type/Interface ที่มีข้อมูลหลายชั้นมากจนเกินไป ตาม Practice แล้วควรจะ Refactor ด้วยการสร้าง Type/Interface เพิ่มเติม และตั้งชื่อให้เข้าใจได้ง่าย จากตัวอย่างเรามี Interface Res
หน้าตาแบบนี้
เราสามารถแยกออกมาเป็น Interface ย่อยๆ ได้ คล้ายๆ กับการแยกตัวแปรเลย แบบนี้
2. Fix warnings
จะมีบ่อยคร้ัง ที่เราทำงานกับเว็บแล้วเรียกฟังก์ชั่นที่ "อาจคืนค่าเป็น null
" ก็ได้ เช่นกรณีนี้เราจะหา HTML Element ที่มีไอดีเป็น app เช่น <div id="app">
แต่ถ้าเราไม่มี Element นี้บนหน้าเว็บเลย ฟังก์ชั่นนี้จะคืนค่า null
แทน และโค้ดนี้จะพังเพราะว่าไม่สามารถใช้ innerHTML
ได้
ถ้าลองชี้ที่ getElementById ดู มันจะบอกว่า ฟังก์ชั่นนี้คืน HTMLElement | null
เราอาจแก้ด้วยการเช็คก่อนว่าค่านั้นเป็น null
หรือไม่ แต่จะทำให้โค้ดดูยาวขึ้นโดยไม่จำเป็น
กรณีนี้เรารู้อยู่แก่ใจว่ามีไอดี app
อยู่แน่นอน และจะทำการ "บังคับ" ให้ไม่มี Error โดยการใช้ Non-null operator หรือเครื่องหมาย !
เป็นการบอกกับ TypeScript ว่าเรามั่นใจว่าโค้ดไม่ Return null
แน่ๆ
เมื่อทำแบบนี้แล้วเส้นแดง Warning ก็จะหายไปแล้ว (แต่ว่าถ้าเราไม่มีไอดี app
อยู่จริง แอปก็จะพังอยู่ดีนะ ฉะนั้นไม่ควรใช้ Non-null operator พรำ่เพรื่อ)
Code ทั้งหมด (เฉพาะ TypeScript)
จากทั้งหมดนี้ เราจะเห็นประโยชน์ในการใช้งาน TypeScript ในการทำเว็บ ทั้งการใช้ประโยชน์จาก Intellisense เพื่อช่วยแนะนำในการเขียนโค้ดต่างๆ ได้ รวมถึงการ Type Check ที่จะเตือนเราด้วย Error หรือ Warning เมื่อโค้ดบางจุดมีโอกาสที่จะเกิดบั๊กได้ ทำให้เราระมัดระวังและเขียนโค้ดได้อย่างมั่นใจมากขึ้น และการสร้าง Type/Interface เองทำให้เราหรือคนอื่นที่มาแก้โค้ด เข้าใจ Structure ได้ดีขึ้นด้วย
Last updated