이 글은 Dev quiz 어플리케이션 null의 퀴즈 해설을 위한 글입니다.
보러가기 -> https://github.com/0hhanum/null_ios
question:
- 다음 중 interface와 객체 타입 별칭(type alias)이 공통적으로 가지는 특징은?
========================================
choices:
- "Mapped type 정의"
- "명시적 확장(extends)"
- "유니온 타입의 결과값"
- "인덱스 시그니처 지원"
========================================
answer:
- D
문제의 세 가지 보기는 개인적으로 객체의 타입을 생성할 때 type alias
와 interface
의 가장 큰 차이점이라고 생각하는 부분들입니다.
선언 병합이나 암묵적 인덱스 시그니처 등의 차이점도 있지만 그로 비롯되는 interface
의 단점들은 깨끗한 코드와 네임스페이스를 통해 해결 가능하다고 생각합니다.
Mapped type은 다음과 같이 정의됩니다.
type MappedType<T> = {
[P in keyof T]: T[P];
};
맵드 타입을 사용하면 기존 타입을 기반으로 새로운 타입을 유연하게 생성하고 조정해 복잡한 타입 작업을 보다 쉽게 처리할 수 있습니다.
다음과 같은 방식으로 사용됩니다.
interface LoginForm {
username: string;
password: string;
}
// 폼 필드의 유효성
type FieldValidity<T> = {
[P in keyof T]: boolean; // 맵드 타입
};
type LoginFormValidity = FieldValidity<LoginForm>;
인터페이스를 확장하려면 extends 키워드를 사용합니다.
이 방식은 상속과 유사하게, 기본 인터페이스의 모든 속성을 상속받은 새로운 인터페이스를 생성합니다.
관계를 명확하게 정의하고 재사용성을 높이는 데 사용할 수 있습니다.
아래와 같이 사용됩니다.
interface User {
id: number;
name: string;
}
interface AdminUser extends User {
permissions: string[]; // permissions 속성 추가
}
const admin: AdminUser = {
id: 1,
name: "Admin",
permissions: ["create", "read", "update", "delete"],
};
type alias
에서는 인터섹션 타입(&)을 통해 비슷한 효과를 낼 수 있습니다.
type User = {
id: number,
name: string,
};
type AdminPermission = {
permissions: string[],
};
type AdminUser = User & AdminPermission;
const admin: AdminUser = {
id: 1,
name: "Admin",
permissions: ["create", "read", "update", "delete"],
};
위 예시에서
type AdminUser = User & AdminPermission;
가 유니온 타입을 통한 타입 정의입니다.
interface AdminUser = User & AdminPermission // 불가능
interface AdminUser extends User & AdminPermission {} // 불가능
위와 같은 방식으로는 interface
를 정의할 수 없습니다.