Typealias คือการประกาศใน Swift ที่สร้างชื่ออื่นสำหรับชนิดที่มีอยู่โดยไม่ต้องกำหนดชนิดใหม่ ชื่อแทนนั้นเทียบเท่ากับชนิดเดิมอย่างสมบูรณ์ในเวลาคอมไพล์ — คอมไพเลอร์จะแทนที่ชนิดเดิมทุกที่ที่ใช้ typealias ตามคู่มือ Swift Language Guide (2025) typealias ใช้เพื่อย่อลายเซ็นที่ยาว ทำให้ชนิดภายในเป็นนามธรรมผ่าน associatedtype ในโปรโตคอล และทำให้พารามิเตอร์ generic ที่ซับซ้อนง่ายขึ้น แตกต่างจาก wrapper ชนิด typealias ไม่ได้เพิ่มความปลอดภัยของชนิด — มันเป็นเพียงชื่อแทนที่ระบบชนิดไม่แยกความแตกต่าง
ประเด็นสำคัญ
typealias NewName = ExistingType — สามารถประกาศได้ทุกระดับ (ทั่วโลก, ภายใน, ภายในชนิด)typealias Result = Swift.Result<Data, Error>typealias Handler = (Int) -> VoidTypealias คือการประกาศใน Swift ที่แนะนำชื่ออื่นสำหรับชนิดที่มีอยู่ หลังจากประกาศ typealias แล้ว ชื่อใหม่สามารถใช้ได้ทุกที่ที่คาดหวังชนิดเดิม — คอมไพเลอร์ถือว่ามันเหมือนกัน Typealias ไม่ได้เพิ่มการแยกทางความหมาย: ค่าของชนิด UserID (typealias สำหรับ String) สามารถส่งไปยังฟังก์ชันที่คาดหวัง String โดยไม่มีข้อผิดพลาด
วัตถุประสงค์หลักของ typealias คือการย่อชื่อยาว บันทึกวัตถุประสงค์ของชนิด และทำให้การใช้งานเป็นนามธรรม ตัวอย่างเช่น typealias JSON = [String: Any] ระบุอย่างชัดเจนว่าพจนานุกรมถูกใช้เป็นโครงสร้าง JSON และ typealias Completion = (Result<Data, Error>) -> Void เปลี่ยนลายเซ็น closure ที่ซับซ้อนเป็นชนิดที่อ่านได้
ตาม Swift.org (2025) typealias ถูกใช้อย่างแพร่หลายในไลบรารีมาตรฐาน ตัวอย่างเช่น String เป็น typealias สำหรับ String (Array<Character> ที่เชี่ยวชาญ) แม้ว่าใน Swift เวอร์ชันสมัยใหม่การใช้งานนี้จะถูกซ่อนไว้ Void เป็น typealias สำหรับทูเพิลว่าง () ซึ่งทำให้ลายเซ็นฟังก์ชันอ่านง่ายขึ้น
ใช้ typealias เพื่อบันทึกความหมายของชนิด แต่จำไว้ว่ามันไม่ได้ป้องกันการผสมแนวคิดที่แตกต่างของชนิดพื้นฐานเดียวกัน สำหรับการแยกที่ปลอดภัยของชนิด ให้ใช้ wrapper (struct wrapper)
Typealias ประกาศด้วยคีย์เวิร์ด typealias ตามด้วยชื่อใหม่ เครื่องหมายเท่ากับ และชนิดที่มีอยู่ รูปแบบพื้นฐาน:
typealias Name = ExistingType
typealias UserID = Int
typealias JSONDictionary = [String: Any]
ขอบเขตของ typealias ถูกกำหนดโดยตำแหน่งที่ประกาศ:
| ระดับ | ตัวอย่าง | การมองเห็น |
|---|---|---|
| ทั่วโลก | typealias Name = String | ทั้งโมดูล (ขึ้นอยู่กับการควบคุมการเข้าถึง) |
| ภายในชนิด | struct User { typealias ID = Int } | User.ID — เข้าถึงได้ผ่านชนิด |
| ภายในฟังก์ชัน | func f() { typealias Local = Int } | เฉพาะภายในฟังก์ชัน |
| ภายในโปรโตคอล | protocol P { associatedtype T } | ระบุเมื่อนำไปใช้ |
Typealias ภายในชนิด (ตัวอย่างเช่น User.ID) เป็นรูปแบบทั่วไปสำหรับการจัดกลุ่มชื่อแทนที่เกี่ยวข้อง ซึ่งช่วยปรับปรุงการจัดเนมสเปซ: Order.ID และ User.ID ต่างก็เป็น Int แต่อ่านเป็นแนวคิดที่แตกต่างกัน การเข้าถึง typealias ที่ซ้อนกันทำได้ผ่าน User.ID หรือผ่านเครื่องหมายจุดหากทราบชนิด
หนึ่งในการใช้งานที่พบบ่อยที่สุดของ typealias คือการทำให้ลายเซ็น closure ง่ายขึ้น ชนิด closure ใน Swift อาจยุ่งยาก โดยเฉพาะกับ Optional และพารามิเตอร์ generic Typealias เปลี่ยน (Data?, Error?) -> Void เป็น FetchResultHandler ที่อ่านได้:
typealias FetchResultHandler = (Data?, Error?) -> Void
func fetchUser(id: Int, completion: FetchResultHandler) {
// network request
completion(data, nil)
}
ตามคู่มือสไตล์ของ Ray Wenderlich typealias สำหรับ closures ปรับปรุงการอ่านลายเซ็นของเมธอด โดยเฉพาะอย่างยิ่งในโปรโตคอลการมอบหมายและรูปแบบ callback อย่างไรก็ตาม หลีกเลี่ยงชื่อแทนที่มากเกินไป — หาก closure ถูกใช้ในที่เดียว สามารถประกาศแบบอินไลน์ได้
ไลบรารีมาตรฐาน Swift ใช้แนวทางนี้อย่างแข็งขัน ตัวอย่างเช่น DispatchQueue.WorkItem เป็น typealias สำหรับ DispatchWorkItem แม้ว่าภายนอกจะดูเหมือนชนิดแยกต่างหาก Typealias สำหรับ closures เป็นเครื่องมือในการอ่าน — อย่าใช้มากเกินไป: 3–5 ชื่อแทน closure ต่อโมดูลเป็นขีดจำกัดที่สมเหตุสมผล
Typealias สามารถรวมพารามิเตอร์ generic เพื่อสร้างเวอร์ชันเฉพาะของชนิด generic ซึ่งมีประโยชน์โดยเฉพาะเมื่อทำงานกับ Result, Publisher และชนิด generic อื่นๆ จากไลบรารีมาตรฐานและ Combine:
typealias FetchResult = Result<Data, Error>
typealias AnyPublisherOfData = AnyPublisher<Data, Error>
func loadData() -> FetchResult {
// data loading
}
คุณยังสามารถสร้าง typealias ด้วยพารามิเตอร์ generic ที่กำหนดเองซึ่งถูกส่งต่อไปยังชนิดเดิม:
typealias NetworkResult<T> = Result<T, NetworkError>
func fetchUser() -> NetworkResult<User> {
// ...
}
กฎสำคัญ: typealias ไม่สามารถเพิ่มข้อจำกัด generic ใหม่ (where clauses) — มันเพียงส่งต่อพารามิเตอร์ไปยังชนิดเดิม หากต้องการข้อจำกัดเพิ่มเติม ให้สร้าง struct หรือ class generic ตาม Swift by Sundell (2024) typealias กับ generics เป็นวิธีที่เหมาะในการย่อลายเซ็นที่ซ้ำซากในโครงการที่ใช้ Combine, Result และ async/await อย่างหนัก
Associatedtype คือ typealias ที่ประกาศภายในโปรโตคอลซึ่งกำหนดชนิดที่เกี่ยวข้อง แตกต่างจาก typealias ทั่วไป associatedtype ไม่ผูกกับชนิดเฉพาะในเวลาประกาศ — มันถูกระบุโดยแต่ละชนิดที่นำโปรโตคอลไปใช้:
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
}
struct IntBox: Container {
typealias Item = Int
// implementation
}
struct StringBox: Container {
typealias Item = String
// implementation
}
Associatedtype ให้ความยืดหยุ่นของชนิด generic แก่โปรโตคอลโดยไม่ต้องระบุชนิดที่เป็นรูปธรรม ณ จุดประกาศ นี่คือพื้นฐานของหลายรูปแบบ Swift: Collection (Element), IteratorProtocol (Element), Identifiable (ID) คอมไพเลอร์สามารถอนุมาน associatedtype โดยอัตโนมัติจากการใช้งาน ดังนั้น typealias Item = Int ที่ชัดเจนมักถูกละไว้ — Swift อนุมาน Item เป็น Int จากพารามิเตอร์ของเมธอด append
ตาม Swift Evolution SE-0195 (2022) ชนิดผลลัพธ์ทึบแสง (some Container) ถูกนำมาใช้สำหรับการทำงานกับโปรโตคอลที่มี associatedtype — ซึ่งแก้ไขปัญหา PAT (โปรโตคอลที่มีชนิดที่เกี่ยวข้อง) ที่ป้องกันไม่ให้ใช้โปรโตคอลดังกล่าวเป็นชนิดตัวแปร
ความแตกต่างหลัก: Typealias เป็นเพียงอีกชื่อหนึ่งสำหรับชนิดที่มีอยู่ ในขณะที่ wrapper เป็นชนิดใหม่ที่แยกทางความหมายจากชนิดเดิม หากคุณประกาศ typealias UserID = Int แล้ว UserID และ Int สามารถใช้แทนกันได้ — ฟังก์ชันที่คาดหวัง Int จะยอมรับ UserID โดยไม่มีข้อผิดพลาด
wrapper ถูกสร้างขึ้นผ่าน struct และให้ความปลอดภัยของชนิดที่แท้จริง:
struct UserID: RawRepresentable {
let rawValue: Int
}
struct OrderID: RawRepresentable {
let rawValue: Int
}
// Compilation error: cannot pass OrderID where UserID is expected
ตาม Point-Free (2025) wrapper เป็นที่นิยมเมื่อแนวคิดที่แตกต่างถูกแสดงด้วยชนิดพื้นฐานเดียวกัน (UserID เทียบกับ OrderID) Typealias ถูกต้องเมื่อเป้าหมายคือการอ่านได้โดยไม่แยก: ย่อชื่อยาว บันทึกความหมาย ทำให้การใช้งานเป็นนามธรรมผ่าน associatedtype เลือก typealias เพื่อความสะดวกในการอ่าน เลือก wrapper เพื่อความปลอดภัยของชนิด
คำถามที่พบบ่อย
Typealias เป็นชื่อแทนสำหรับชนิดที่มีอยู่เฉพาะ Associatedtype ถูกประกาศภายในโปรโตคอลและถูกระบุโดยแต่ละชนิดที่นำโปรโตคอลไปใช้ — ชนิดต่างกันสามารถใช้ associatedtype ต่างกันสำหรับโปรโตคอลเดียวกัน
ไม่ typealias เป็นเพียงชื่ออื่น คอมไพเลอร์แทนที่ด้วยชนิดเดิมในเวลาคอมไพล์ ในการสร้างชนิดใหม่ที่แยกทางความหมาย ให้ใช้ struct wrapper หรือ enum ที่มี rawValue
ได้ typealias สามารถรวมพารามิเตอร์ generic: typealias Result<T> = Swift.Result<T, Error> พารามิเตอร์ generic จะถูกส่งต่อไปยังชนิดเดิม ไม่สามารถเพิ่มข้อจำกัด where — ให้ใช้ struct generic สำหรับสิ่งนั้น
ทุกระดับ: ทั่วโลก (ในไฟล์) ภายในชนิด (struct/class/enum) ภายในฟังก์ชัน ภายในโปรโตคอล (เป็น associatedtype) ขอบเขตถูกกำหนดโดยตำแหน่งประกาศ — typealias ทั่วโลกมองเห็นได้ทั่วทั้งโมดูล typealias เฉพาะที่มองเห็นได้เฉพาะภายในขอบเขตของมัน
เลือก typealias สำหรับการย่อชื่อยาวและบันทึกความหมายเมื่อการสับเปลี่ยนกับชนิดเดิมปลอดภัย เลือก wrapper (struct) เมื่อคุณต้องการป้องกันการผสมแนวคิดที่แตกต่างของชนิดพื้นฐานเดียวกันโดยไม่ตั้งใจ: UserID เทียบกับ ProductID
สรุป
typealias NewName = ExistingType, ขอบเขต — ทั่วโลก, ภายในชนิด, ภายในฟังก์ชันtypealias Handler = (Int) -> Voidเราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ