Swift에서 typealias는 기존 타입에 대한 대체 이름을 정의할 수 있게 해줍니다. 이는 긴 타입이나 복잡한 타입을 단순화하는 데 유용할 수 있습니다. 예를 들어, 클로저 타입이나 제네릭을 다룰 때 유용합니다. typealias를 사용하면 코드의 가독성이 향상되고 유지 관리가 용이해지며, 특히 타입이 자주 변경되거나 여러 곳에서 사용될 때 더욱 그렇습니다.
예를 들어, 다음과 같은 클로저 형식이 자주 나타난다면:
(type: String, completion: (Result<Bool, Error>) -> Void) -> Void
이를 다음과 같이 대체할 수 있습니다:
typealias FetchCompletion = (Result<Bool, Error>) -> Void typealias FetchHandler = (String, FetchCompletion) -> Void
이렇게 하면 메서드와 인터페이스의 시그니처 가독성이 크게 향상됩니다.
복잡한 아키텍처에서 typealias를 사용할 때는 균형을 잘 맞추어야 합니다. 남용할 경우 코드 탐색이 복잡해질 수 있으며, 기존 타입과 이름이 충돌할 경우 혼란을 초래할 수 있습니다.
typealias를 사용하여 새로운 독립 타입을 만들거나 기존 타입의 동작을 변경할 수 있나요?
답변: 아닙니다. typealias는 단순히 기존 타입에 대한 대체 이름을 생성할 뿐, 새로운 기능을 추가하거나 동작을 변경하지 않습니다. 예를 들어:
typealias UserID = String let id: UserID = "123" let str: String = id // 올바릅니다: UserID와 String는 동일한 타입입니다.
UserID와 String은 사실상 완전히 상호 교환 가능하며, 새로운 타입이 아닙니다.
이야기
대형 프로젝트에서 typealias를 다양한 식별자에 사용하기 시작했습니다: typealias UserID = String, typealias ProductID = String. 서비스 메서드에서 ProductID를 UserID를 기대하는 인수로 오류로 전달하게 되었고, 이는 컴파일 단계나 테스트에서 드러나지 않았으며, 이후 데이터 무결성에 문제를 일으켰습니다.
이야기
프로토콜에서 긴 typealias 체인을 사용하여 공개 API 읽기에 혼란을 초래했습니다: typealias Output = Result<Bool, MyError>, typealias ServiceResult = Output. 새로운 개발자는 이를 서로 다른 타입으로 잘못 가정하고 오류 처리를 잘못 구현하였습니다.
이야기
기존 모듈에서 의존 프레임워크의 사용자 정의 타입과 이름이 일치하는 typealias를 선언했습니다. 이는 타입의 충돌과 모호성을 초래하였고, 이는 종속성 구성 및 로딩 시에만 발견되어 버그 찾기와 수정이 복잡해졌습니다.