ประเภทกับส่วนต่อประสานใน TypeScript
เผยแพร่แล้ว: 2022-11-02Type 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