ประเภทกับส่วนต่อประสานใน TypeScript

เผยแพร่แล้ว: 2022-11-02

Type vs. Interface เป็นหนึ่งในสิ่งที่สับสนและน่าสนใจที่สุดใน TypeScript เราจะพยายามเคลียร์ความสับสนนั้น

TypeScript ถูกสร้างขึ้นบน JavaScript ซึ่งเพิ่ม ประเภทสแตติก การมีประเภทเป็นสิ่งที่ยอดเยี่ยมสำหรับนักพัฒนา ประเภทการเขียนจะยาก แต่คุณจะไม่เสียใจในระยะยาว

TypeScript มีประเภทพื้นฐานทั้งหมด เช่น ตัวเลข สตริง บูลีน ฯลฯ นอกจากประเภทพื้นฐานแล้ว TypeScript ยังช่วยให้เราสร้างประเภทที่กำหนดเองและกำหนดลักษณะของวัตถุด้วยความช่วยเหลือของ Type Aliases และ Interfaces ตามลำดับ

Type Alias ​​ไม่ใช่แค่ประเภทเท่านั้น การสร้างประเภทด้วยชื่อที่กำหนดเอง (นามแฝง) ทำให้เป็นประเภทนามแฝง ไม่มีอะไรมากไปกว่านั้น

มาดูไวยากรณ์พื้นฐานของ Interfaces และ Type Aliases

ไวยากรณ์พื้นฐาน

อินเทอร์เฟซ

อินเตอร์เฟสจะถูกประกาศด้วยคำสำคัญ interface ตรวจสอบไวยากรณ์ของอินเทอร์เฟซด้านล่าง

 interface InterfaceName { keyName: typeOfKey ... }

ดูตัวอย่างตัวอย่างด้านล่าง

 interface Site { name: string; url: string; pagesCount: number; } const geekflare: Site = { name: 'Geekflare', url: 'https://geekflare.com/', pagesCount: 25 }

พิมพ์นามแฝง

นามแฝงประเภทจะถูกประกาศโดยใช้คำสำคัญ type ตรวจสอบไวยากรณ์ของนามแฝงประเภทด้านล่าง

 type TypeName = { keyName: typeOfKey; ... }

ดูตัวอย่างตัวอย่างด้านล่าง

 type Site = { name: string; url: string; pagesCount: number } const geekflare: Site = { name: 'Geekflare', url: 'https://geekflare.com/', pagesCount: 25 }

เราได้สร้างประเภทสำหรับ Site โดยใช้ อินเทอร์เฟซ และ ประเภทนามแฝง ทั้งสองรายการถูกต้องและสามารถใช้ได้กับประเภทวัตถุที่กล่าวถึงในตัวอย่าง เฉพาะไวยากรณ์เท่านั้นที่แตกต่างกันในตัวอย่างข้างต้น ซึ่งเห็นได้ชัด

มาสำรวจความแตกต่างระหว่างกันเพื่อค้นหาสิ่งต่างๆ เพิ่มเติม

ทูเปิลส์

tuple ใน TypeScript คืออาร์เรย์ความยาวที่กำหนดไว้ล่วงหน้าที่พิมพ์ออกมา กำหนดประเภทของดัชนีแต่ละตัว

เราสามารถประกาศ tuples โดยใช้ชื่อแทนประเภท แต่เราไม่สามารถทำได้โดยใช้อินเทอร์เฟซ เรามาดูวิธีการทำกับนามแฝงประเภท

 type Site = [string, string, number] const geekflare: Site = ['Geekflare', 'https://geekflare.com/', 25]

ในตัวอย่างข้างต้น เราได้กำหนดประเภทขององค์ประกอบดัชนีแต่ละรายการสำหรับอาร์เรย์ หากเราระบุประเภทอื่นในอาร์เรย์ TypeScript จะแสดงข้อผิดพลาด

เราทำกับอินเทอร์เฟซไม่ได้หรือ

เราไม่สามารถทำได้เหมือนกับที่เราทำกับนามแฝงประเภท อินเทอร์เฟซใช้สำหรับประเภทวัตถุ ดังนั้น เราจำเป็นต้องมีทูเพิลภายในอ็อบเจ็กต์เพื่อใช้ในอินเทอร์เฟซ มาดูตัวอย่างกัน

 interface Site { details: [string, string]; pagesCount: number; } const geekflare: Site = { details: ['Geekflare', 'https://geekflare.com/'], pagesCount: 25, }

หากคุณเห็นโค้ด แสดงว่าเรามี tuple ที่เรียกว่า รายละเอียด ภายในอินเทอร์เฟซ ดังนั้นเราจึงสามารถใช้สิ่งอันดับภายในอินเทอร์เฟซได้

ในทำนองเดียวกัน เราสามารถใช้นามแฝงประเภทสำหรับประเภทเดียว เช่น สตริง ตัวเลข บูลีน เป็นต้น เนื่องจากอินเทอร์เฟซใช้สำหรับประเภทอ็อบเจ็กต์ เราจึงสามารถใช้อินเทอร์เฟซสำหรับประเภทเดียว เช่น ชื่อแทนประเภท

สิ่งที่น่าสนใจอีกประการหนึ่งคือเราสามารถใช้ ชื่อแทน tuple ใน อินเทอร์เฟซ ได้ ตรวจสอบตัวอย่างด้านล่าง

 type Details = [string, string] interface Site { details: Details; pagesCount: number; } const geekflare: Site = { details: ['Geekflare', 'https://geekflare.com/'], pagesCount: 25, }

มาต่อกันที่เรื่องต่อไป

การรวมการประกาศ – อินเตอร์เฟส

การรวมการประกาศใช้ TypeScript เพื่อรวมประเภทของอินเทอร์เฟซที่มีชื่อเดียวกัน มาดูตัวอย่างกันเพื่อความชัดเจนมากขึ้น

 interface Site { name: string; } interface Site { url: string; } interface Site { pagesCount: number; } const geekflare: Site = { name: 'Geeflare', url: 'https://geekflare.com/', pagesCount: 25, }

หากคุณเห็นโค้ดข้างต้น แสดงว่าเราได้ประกาศอินเทอร์เฟซที่มีชื่อเดียวกัน 3 ครั้งแล้ว คอมไพเลอร์ TypeScript จะคอมไพล์ทั้ง 3 ฟอร์มเหล่านั้นเป็นประเภทอ็อบเจกต์เดียวซึ่งรวมถึงทุกประเภทจากอินเทอร์เฟซที่มีชื่อเดียวกัน

คุณสามารถยืนยันการรวมการประกาศโดยลบหนึ่งคีย์ออกจากวัตถุ geekflare หากคุณลบปุ่มใดปุ่มหนึ่งออกจาก geekflare คุณจะเห็นข้อผิดพลาด

เราไม่สามารถทำสิ่งเดียวกันกับนามแฝงประเภทได้ คนส่วนใหญ่ไม่ได้ใช้คุณสมบัตินั้น โดยทั่วไป การมีหลายอินเทอร์เฟซที่มีชื่อเดียวกันทำให้เกิดความสับสน

พิมพ์ alias fans ไม่ต้องกังวลเกี่ยวกับคุณลักษณะของอินเทอร์เฟซนี้

ขยาย

สมมติว่าคุณได้ประกาศประเภท ตอนนี้ คุณต้องการประกาศประเภทอื่นพร้อมกับประเภทของประเภทก่อนหน้า ในกรณีนั้นเราสามารถขยายประเภทก่อนหน้าได้ เราสามารถทำได้ทั้ง อินเทอร์เฟซ และ ประเภทนามแฝง

มาดูกันทั้งคู่

อินเทอร์เฟซ

มีคีย์เวิร์ดที่เรียกว่า extends สำหรับกรณีการใช้งานนี้ใน TypeScript เราจะใช้มันเพื่อขยายส่วนต่อประสาน มาดูตัวอย่างกัน

 interface Site { name: string; url: string; pagesCount: number; } interface Geekflare extends Site { founder: string; } const geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

เราได้สร้างส่วนต่อ Geekflare โดยขยายส่วนต่อประสาน Site Site ทุกประเภทจะปรากฏในส่วนต่อประสานของ Geeflare พร้อมกับประเภทของตนเอง คุณสามารถลบคีย์ name ออกจากตัวแปร geekflare เพื่อยืนยันได้

เราสามารถขยายหลายอินเตอร์เฟสได้ดังนี้

 interface FirstHalf { name: string; } interface SecondHalf { age: number } interface Person extends FirstHalf, SecondHalf { profession: string } const person: Person = { name: 'Geekflare', age: 7, profession: 'Helping Techies' }

ลองขยายด้วยอินเทอร์เฟซมากกว่า 2 แบบเพื่อความสนุกสนาน นอกจากนี้เรายังสามารถขยาย ชื่อแทนประเภท ด้วยอินเทอร์เฟซ

 type Site = { name: string; url: string; pagesCount: number; } interface Geekflare extends Site { founder: string; } const geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

เราได้ขยายประเภทเดียวเท่านั้นในตัวอย่างข้างต้น คุณสามารถขยายได้มากเท่าที่ต้องการ คล้ายกับตัวอย่างก่อนหน้าของการขยายหลายอินเทอร์เฟซ

เรามาดูวิธีการทำกับนามแฝงประเภท

พิมพ์นามแฝง

เราสามารถขยายชื่อแทนประเภทโดยใช้ ประเภททางแยก ใน TypeScript มาดูตัวอย่างกัน

 type Site = { name: string; url: string; pagesCount: number; } type Geekflare = Site & { founder: string; } const geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

เราได้ขยายประเภท Site ด้วย founder ประเภท Geekflare โดยใช้ ทางแยก (&) คุณสามารถทดสอบได้โดยลบคีย์ใดคีย์หนึ่งออกจากตัวแปร geekflare ซึ่งจะทำให้เกิดข้อผิดพลาด

เช่นเดียวกับอินเทอร์เฟซ เราสามารถขยายได้หลายประเภทดังนี้

 type FirstHalf = { name: string; } type SecondHalf = { age: number } type Person = FirstHalf & SecondHalf & { profession: string } const person: Person = { name: 'Geekflare', age: 7, profession: 'Helping Techies' }

นอกจากนี้เรายังสามารถขยายส่วนต่อประสานที่มีนามแฝงประเภทได้เช่นเดียวกับส่วนต่อประสานที่ขยายนามแฝงประเภท ตรวจสอบตัวอย่างด้านล่าง

 interface Site { name: string; url: string; pagesCount: number; } type Geekflare = Site & { founder: string; } const geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

ลองขยายการรวมกันของนามแฝงประเภทและอินเทอร์เฟซ

กำลังดำเนินการ

นี่ไม่ใช่ความแตกต่างระหว่างอินเทอร์เฟซและนามแฝงประเภท เป็นเพียงคุณสมบัติของ class ที่จะรู้

คลาสสามารถใช้ทั้งอินเทอร์เฟซและนามแฝงประเภทในลักษณะเดียวกัน มาดูตัวอย่างของทั้งคู่กัน

อินเทอร์เฟซ

 interface Site { name: string; url: string; pagesCount: number; } class Geekflare implements Site { name = 'Geekflare' url = 'http://geekflare.com/' pagesCount = 25 constructor() { console.log(this.name, this.url, this.pagesCount) } }

พิมพ์นามแฝง

 type Site = { name: string; url: string; pagesCount: number; } class Geekflare implements Site { name = 'Geekflare' url = 'http://geekflare.com/' pagesCount = 25 constructor() { console.log(this.name, this.url, this.pagesCount) } }

หมายเหตุ: สิ่งหนึ่งที่ต้องจำไว้คือเราไม่สามารถใช้ประเภท สหภาพ (|) หรือ ทางแยก (&) กับคลาสได้

คำพูดสุดท้าย

ดังที่คุณเห็นในบทความ เราสามารถทำทุกอย่างด้วยชื่อแทนประเภทและอินเทอร์เฟซ ดังนั้นเราจึงไม่สามารถพูดได้อย่างชัดเจนว่าอันหนึ่งดีกว่าอีกอันหนึ่ง ในท้ายที่สุด มันเป็นทางเลือกส่วนบุคคลที่จะเลือกหนึ่งในนั้น คุณจะพัฒนารูปแบบการใช้งานของคุณในที่สุด

ถัดไป คุณสามารถตรวจสอบ typescript กับ Javascript

Happy Coding