타입스크립트의 인터페이스(interface)는 객체의 구조를 표현하는 강력한 방법으로, 주로 객체의 형태를 정의하며 클래스가 특정 조건을 충족하도록 강제할 수도 있습니다. 인터페이스는 구현해야 할 속성과 메서드를 규정할 수 있으며, 필수 항목 뿐만 아니라 선택적 항목도 정의할 수 있습니다. 또한, 인터페이스는 코드 내에서 사용할 특정 형태의 객체를 명시하는 데도 사용됩니다.
interface Person {
readonly name: string; // readonly property
age?: number; // optional property
sayHi(): void; // method
// method overloading
sayHi: (a: number, b: number) => void; // ❌ No
sayHi: (a: number, b: number): void; // ✅ Ok (call signature)
}
const person: Person = {
name: "이정환",
sayHi: function () {
console.log("Hi");
},
};
person.name = "홍길동"; // ❌ No
preson.sayHi();
person.sayHi(1, 2);
// hybrid type
interface Func2 {
(a: number): string;
b: boolean;
}
const func: Func2 = (a) => "hello";
func.b = true;
// interface를 정의할 때 intersection이나 union을 활용할 수 없으므로 타입 별칭이나 타입 주석에 활용해야 합니다.
type Type1 = number | string | Person;
type Type2 = number & string & Person;
const person: Person & string = {
name: "이정환",
age: 27,
};
참조: 타입스크립트 type과 interface의 공통점과 차이점
인터페이스를 확장한다는 것은 extends
키워드를 사용하여 한 인터페이스가 다른 인터페이스를 상속하여 그 속성을 확장한다는 것을 의미합니다.
interface Animal {
name: string;
age: number;
}
interface Dog extends Animal {
name: "hello"; // 서브셋에서 타입을 재정의할 수 있습니다.
isBark: boolean;
}
interface Cat extends Animal {
isScratch: boolean;
}
interface Chicken extends Animal {
isFly: boolean;
}
// multi interface extends
interface DogCat extends Dog, Cat {}
const dogCat: DogCat = {
name: "",
color: "",
isBark: true,
isScratch: true,
}
인터페이스 선언 합치기는 동일한 이름을 가진 인터페이스 선언이 자동으로 병합되는 타입스크립트의 기능입니다. 이를 이용하면 동일한 이름의 인터페이스를 여러 번 선언하여 그것들이 단일 인터페이스를 구성하게 할 수 있습니다.
하지만, 주의할 점은 이미 선언된 필드의 타입은 변경되지 않는다는 것입니다. 즉, 이미 선언된 필드의 타입을 변경하려고 하면 오류가 발생합니다. 새로운 필드를 추가하는 것은 가능합니다.
인터페이스 선언 병합은 타입 별칭에서는 허용되지 않습니다. 인터페이스만이 이 기능을 지원합니다.
type Person = {
name: string;
};
type Person = { // ❌ No: 타입 별칭에서는 같은 이름으로 선언할 수 없습니다.
age: number;
}
// 인터페이스 선언 병합: 같은 이름을 가진 인터페이스는 선언 병합이 가능합니다.
interface Person { // ✅ OK: 동일한 이름의 인터페이스를 선언하면 필드가 병합됩니다.
name: string;
}
interface Person {
name: "hello"; // ❌ No: 선언 병합 시, 이미 정의된 필드의 타입은 변경될 수 없습니다.
age: number; // ✅ OK: 새로운 필드를 추가하는 것은 가능합니다.
}
// 인터페이스 확장: 상속 시 서브타입을 허용합니다.
interface Developer extends Person {
name: "hello"; // ✅ OK: "Person"을 확장하는 "Developer"에서 "name" 필드의 타입을 변경할 수 있습니다.
}
const person: Person = { // "Person" 인터페이스는 "name"과 "age" 필드를 가지게 됩니다.
name: "",
age: 27,
};
Reference