TypeScript: Type Annotations กับ Type Inference ใช้อันไหนดี ??
สวัสดีครับวันนี้อยากจะมาแชร์เรื่องความต่างกันของ Type Annotation กับ Type Inference ของเจ้าตัว TypeScript (TS) กัน
ว่ากันแบบบ้าน ๆ …
Type Annotations: เป็นการเขียนโค้ดที่ developer จะบอก TS ว่า ตัวแปร/ function/ object นั้นมี type เป็นอะไร
Type Interface: เป็นการปล่อยให้ตัว TS จัดการเรื่อง type ของ ตัวแปร/ function/ object ให้เองโดยอัตโนมัติ
อ่านดูแล้วมันก็ดูเหมือน ๆ กันอยู่นาาา… แล้วเราควรจะเลือกเป็นคนกำหนด type เองแบบ manual หรือจะให้ TS จัดการเองดี ละ ?? (เก็บคำถามไว้ในใจ)
Code Example
เริ่มกันที่การประกาศตัวแปรแบบ Type Annotations
จากรูป 1 ใช้ : <type> ตามหลังชื่อตัวแปร จะได้ว่า a เป็นตัวแปร type number ที่มีค่าเริ่มต้นเท่ากับ 5
สังเกตว่าเราจะไม่สามารถกำหนดค่าให้ a เป็นค่าชนิดอื่นที่ไม่ใช่ number ได้, TS จะทำการแจ้ง error ออกมา
ซึ่งก็แน่นอนว่าการกำหนด type นั้น สามารถกำหนดได้ทั้ง primitive type (number, string, boolean, null, undefined) และ object type (array, object, function, class) ดังรูป 2
รูปที่ 3 ประกาศตัวแปร ด้วย object type
- ตัวแปรชนิด array ก็ให้ใส่ [] ไว้หลัง type
- ตัวแปรชนิด object ที่เป็น built in ของ TS , TS ก็สามารถบอก error ได้ถ้า developer กำหนดค่าที่ไม่ตรง type เข้าไป
- ตัวแปรชนิด object แบบ literal (key, value) ซึ่งจะสังเกตว่าถ้าเรากำหนดค่าไม่ตรงกับ type หรือ กำหนดค่ากับ key ที่ไม่ได้ระบุไว้ type ไว้ตัว TS ก็จะแสดง error ออกมา
- ตัวแปรชนิด class ก็มองเป็น type ชนิดหนึ่ง เมื่อเราสร้าง instance (car) แล้วกำหนดค่าใน field ผิด type TS ก็จะแสดง error ออกมา
- ตัวแปรชนิด function / anonymous function ให้ทำการระบุ type ที่ตัว parameter และระบุ type ที่จะ return ของ function โดยหากเราส่งข้อมูลไปยัง parameter ที่ผิด type หรือ return ค่าของ function ออกมาผิด type TS ก็จะแสดง error มาบอกเราด้วยเช่นกันเน่อ
เราย้ายมาดูคู่แข่งกันบ้าง Type Inference
การเขียนแบบ Type Inference นั้นก็คือ ไม่ต้องกำหนด type ให้ตัวแปรนั่นเอง (หรือเป็นการให้ TS เป็นคนระบุ type ให้) ดังรูปที่ 4
งั้นก็สบายเลยสิ จะกำหนด type ให้เมื่อยไปทำไมกันละ …
ช้าก่อน… “ท่านี้หน่ะ (Type Inference) มันง่ายก็จริง แต่มันมีข้อจำกัดหน่ะ!!”
ซึ่งข้อจำกัดนั้นก็คือ เราต้องประกาศตัวแปรพร้อมกำหนดค่าเริ่มต้นให้มันด้วย มิฉะนั้นจะเกิดเหตุการณ์นี้ รูปที่ 5 นั่นคือตัวแปร a ของเราจะเป็น type any ไปซะดื้อๆ ซึ่งการมีตัวแปรเป็น type any นี้เองจะทำให้เกิดความลำบากขึ้นในการพัฒนาต่อ ๆ ไป
สรุป
ก็พอเห็นภาพกันไปแล้วว่าการที่จะเขียน TS ให้เซฟ และเข้าใจโค้ดมากที่สุดคือเราจะต้องเขียนในรูปแบบ Type Annotation ให้ได้มากที่สุด (ทุกที่ที่เป็นไปได้) และหลีกเลี่ยงกันใช้ type any หรือการไม่ได้กำหนด type จน TS ได้ให้ตัวแปรนั้นเป็น type any
เราควรระวังและคำนึงถึงเจ้า any กันไว้ด้วยเน่ออ…. ขอบคุณครับ byee🚀
*(type any: type ที่ TS จะกำหนดให้ในกรณีที่ตัว TS เองไม่รู้ว่าตัวแปร/ function/object นั้นควรมี type เป็นอะไร และทำให้ไม่สามารถเช็คความถูกต้องของ property reference ได้)