ทำความเข้าใจเบื้องหลังของ Utility Type ในภาษา TypeScript — Partial
เกริ่น
ช่วงนี้เรากลับมาทำ Type Challenge อีกครั้ง แล้วรู้สึกว่าการทำความเข้าใจเบื้องหลังการสร้าง Utility Type เป็นหนึ่งในวิธีที่ทำให้เริ่มเข้าใจ และ เข้าสู่โลกของ Advanced Type ใน TypeScript ที่ดีเลยล่ะฮะ
Partial<Type>
Partial เป็น Utility Type ที่รับ Type Parameter เข้ามาหนึ่งตัวในลักษณะของ Object ในรูปแบบ {key01: type01, key02: type02} อะไรประมาณนี้
ผลลัพธ์ที่ได้คือ เราจะได้ Type ที่เป็น Object ตัวนั้น แต่ Key ทุกอันของ Object นั้นๆ จะมีลักษณะเป็น Optional (คือจะใส่ค่าเป็นตาม Type ที่กำหนดใน key หรือ ปล่อยว่างให้มันเป็น undefined ก็ได้)
เบื้องหลังของ Partial<Type>
ซึ่งเบื้องหลังของโค้ด Partial (ซึ่งเราขอยกตัวอย่างเป็น Partial ที่เรา Custom มาเอง ให้มีลักษณะเหมือนกับ Partial จริงๆ) มันจะเป็นอย่างงี้ครับ
type CustomPartial<T> = {
[P in keyof T]?: T[P];
};
จากโค้ดเราจะเห็นได้ว่าเราจะกำหนด Type ที่เป็น Generic Type ที่รับ Type Parameter เป็นตัวแปร T ในลักษณะของ Object เข้ามาหนึ่งตัว
โดยที่เรากำหนดตัวแปรอีกตัวเป็น P เอาไว้แทนค่าของ keyof T (หรือก็คือ P เป็นตัวแปรตัวแทนของ Key ทั้งหมดของ T)
โดยที่ถ้าเราสังเกตดีๆจะมีเครื่องหมาย “?” ตามหลัง [p in keyof T] เป็นการสื่อว่า ให้ทั้งก้อนในวงเล็บที่สื่อว่า P เป็นตัวแปรแทน Key ทั้งหมดของ T (Object Type) โดยให้ key ทั้งหมดเนี่ยมีลักษณะเป็น Optional หมายความว่า Key ทุกตัวใน Object นั้น ไม่จำเป็นต้องใส่ให้ object ที่ถูก annotate ด้วย Partial Type ตัวนี้
(เครื่องหมาย ? เป็นสัญลักษณ์ในภาษา TypeScript ที่เรามักจะเอาไว้ใช้หลัง key ใน object เพื่อเป็น mark ว่า key นั้นมีลักษณะเป็น Optional หรือบางทีก็ใช้หลัง Parameter ตอนที่สร้างฟังก์ชัน เพื่อบอกว่าเราไม่จำเป็นต้องใส่ Argument เข้าไปแทน Parameter ตัวนี้ทุกครั้งที่สร้างฟังก์ชันเช่นกันฮะ)