วิธี Exclude บาง Property ของการ Inheritance ใน Typescript 🙅🏻‍♂️

Spoiler alert เราจะใช้ Built-in type ที่ชื่อว่า Pick, Exclude และ Keyof กัน

Rungsikorn Rungsikavanich
Digithun
2 min readMar 24, 2019

--

EDIT: เนื่องจากหัวข้อใช้คำว่า Inheritance แต่จริงๆแล้วมันคือการสร้าง Type alias ครับ (เขียนหัวข้อผิด​ ) ขอบคุณ คุณ Aaron, Salah ที่ช่วยคอมเม้นเรื่อง Liskov ครับ 🤘🏼

I am gonna random removing half of those properties no infinity stone required.

Typescript เป็นอีกหนึ่งภาษาที่หน้าสนใจมากในเรื่องความ tricky ของการใช้งาน โดยเฉพาะการเขียน Type definition

วันนี้มาแชร์เรื่องที่ค่อนข้างขั้นกว่า ของการเขียน Typescript ก็คือการทำ Exclude Attribute !!

ที่มาและปัญหา

ลองคิดตามว่าเรากำลังจะทำ 1 Function รับ Input และ Return output โดย Requirement คร่าวๆดังนี้

  • เราจะทำ function สำหรับสร้าง User account
  • รับ input มาเป็น Object ประกอบด้วย 4 fields name, mobileNumber, password
  • จากนั้น Return object ที่มาจาก input แต่เพิ่ม createdAt, id

เราก็เลยเขียน Definition ขึ้นมาเพื่อรองรับ requirement โดย

ยังไม่ถูกต้องใช่ไหม ? เพราะว่าเราไม่ต้องการให้ parameter input ต้องมี id และ createdAt เนื่องจากเป็นหน้าที่ของ CreateNewUserAccount ที่จะ assign value attributes พวกนั้นหลังจากที่ insert เข้าไปใน Database

ถ้างั้นเรามาแก้ให้มันถูกต้องดีกว่า โดยวิธีทำมีหลายแบบ เช่นเราอาจจะทำ output extends input

แต่ปัญหาของการทำแบบนี้คือ เราจะไม่มี Abstract ที่แน่นอนของ User หน่ะสิ ส่วนใหญ่แล้ว การออกแบบ Abstraction เริ่มต้นจากการออกแบบ Entity หลักของ implementation ซึ่งก็คือ UserAccount

โดย UserAccount ก็ควรจะรวมกันอยู่แบบนั้นใน Abstract เดียวเพื่อให้มันอ่านง่าย

แทนที่จะแยกออกมาเป็น 2 abstraction เราควรที่จะใช้ UserAccount เป็น input เหมือนเดิม แต่ EXCLUDE บาง property ออกไป ซึ่งก็คือ id และ createdAt

บางภาษาอาจจะเป็น restrict ที่ไม่สามารถนำ Property ออกจาก type inheritance ได้แต่

Typescript สามารถทำการ สร้าง Type aliasโดยนำบาง Property ออกได้ !!

This is a kind of magic

บางคนอาจจะนึกไม่ออก มันยังไงวะ

เราจะ Exclude บาง Property ออกจาก UserAccount โดยการใช้ Built in type ที่ชื่อว่า Pick, Keyof และ Exclude

สร้าง CreateNewUserAccountInput จากการที่ Pick attributes มาจาก UserAccount โดย Pick จาก keyof UserAccount ที่ Exclude keyof ที่ไม่ต้องการ

และสิ่งที่เราได้มาก็คือ input ที่ alias type มาจาก Entity UserAccount โดยถอดบาง property ออกไป แต่ Return type ยังเป็น UserAccount อยู่

ซ้ายคือ Input ขวา คือ return ซึ่งมาจาก Type เดียวกัน แต่ input มีการ pick แค่ที่ต้องการ

แค่นี้เราก็จะสามารถเขียน Definition type ได้สะอาดสะอ้านกว่าเดิม และ Maintenance ง่ายขึ้นด้วยนะ

วันนี้พอแค่นี้ จริงๆยังมีอีกหลาย Trick มาก ยังไงติดตาม Typescript trick ใหม่ๆได้ใน account ผมนี่แหล่ะครับ 🦄

--

--

Rungsikorn Rungsikavanich
Digithun

The Moderately Enthusiastic Programmer, Javascript coder guy.