[TypeScript] 인터페이스 확장 (Interface Extension)
타입스크립트에서 인터페이스 확장이란, 하나의 인터페이스를 다른 인터페이스들이 상속받아 중복된 프로퍼티를 다시 정의하지 않도록 도와주는 문법이다. 객체지향 프로그래밍의 '상속' 개념과 매우 유사하다. 1. 왜 확장이 필요한가? (중복의 문제) 만약 확 기능을 사용하지 않고 여러 동물의 타입을 정의한다면 어떻게 될까? TypeScript interface Animal { name: string; age: number; } interface Dog { name: string; // 중복 age: number; // 중복 isBark: boolean; } interface Cat { name: string; // 중복 age: number; // 중복 isScratch: boolean; } interface Chicken { name: string; // 중복 age: number; // 중복 isFly: boolean; } Dog, Cat, Chicken 모두 Animal의 특징(name, age)을 가지고 있다. 이렇게 되면 코드가 중복될 뿐만 아니라, 유지보수가 매우 힘들어진다. 만약 Animal의 age를 ages로 수정해야 한다면? 나머지 3개의 인터페이스를 일일이 찾아다니며 모두 수정해야 하는 대참사가 일어난다. --- 2. 인터페이스 확장 사용하기 (extends) 이럴 때 extends 키워드를 사용하면 효율적으로 타입을 정의할 수 있다. TypeScript interface Animal { name: string; color: string; } // Animal을 확장(상속)받음 interface Dog extends Animal { breed: string; } interface Cat extends Animal { isScratch: boolean; } interface Chicken extends Animal { isFly: boolean; } 이제 Dog, Cat, Chicken은 Animal에 정의된 name과 color 프로퍼티를 자동으로 갖게 된다. TypeScript const dog: Dog = { name: "춘식이", // Animal에서 물려받음 color: "brown", // Animal에서 물려받음 breed: "리트리버", // Dog만의 프로퍼티 }; 이때 상속을 해주는 Animal은 슈퍼 타입(부모), 상속을 받는 Dog는 서브 타입(자식) 이 된다. --- 3. 프로퍼티 재정의 (Overriding) 확장과 동시에 부모에게 물려받은 프로퍼티의 타입을 재정의할 수도 있다. TypeScript interface Animal { name: string; color: string; } interface Dog extends Animal { name: "도로롱"; // string -> "도로롱" (Literal Type)으로 재정의 breed: string; } ⚠️ 주의할 점: 타입 호환성 규칙 프로퍼티를 재정의할 때는 반드시 원본 타입의 서브 타입으로만 재정의할 수 있다. TypeScript interface Animal { name: string; color: string; } interface Dog extends Animal { name: number; // ❌ 에러 발생! breed: string; } 왜 안 될까?Dog가 Animal을 확장한다는 것은 Dog가 Animal의 서브 타입(자식)이 된다는 뜻이다. 하지만 name을 number로 바꿔버리면, Dog는 더 이상 Animal(name이 string인 집합)에 포함될 수 없게 된다. 따라서 원본 타입의 범위를 벗어나는 재정의는 불가능하다. --- 4. 타입 별칭(Type Alias) 확장하기 재미있는 점은 인터페이스가 인터페이스뿐만 아니라 타입 별칭으로 정의된 객체도 확장할 수 있다는 것이다. TypeScript type Animal = { name: string; color: string; }; // 타입 별칭을 인터페이스가 확장 interface Dog extends Animal { breed: string; } --- 5. 다중 확장 (Multiple Extension) 여러 개의 인터페이스를 동시에 확장하는 것도 가능하다. 콤마(,)를 사용하면 된다. TypeScript interface Dog { name: string; isBark: boolean; } interface Cat { name: string; isScratch: boolean; } // 개이면서 동시에 고양이인 혼종(?) 타입 interface DogCat extends Dog, Cat {} const dogCat: DogCat = { name: "개냥이", isBark: true, isScratch: true, }; --- 요약 1. 인터페이스 확장 (extends): 중복 코드를 줄이고 유지보수성을 높여준다. 2. 프로퍼티 재정의: 가능하지만, 원본 타입의 서브 타입 범위 내에서만 가능하다. 3. 유연성: 타입 별칭(type)도 확장할 수 있으며, 여러 인터페이스를 한 번에 확장(다중 확장)할 수도 있다.