인터페이스 또한 타입 별칭처럼 타입을 정의하는 문법입니다.
interface Person {
name: string;
age: number;
}
인터페이스도 선택적 프로퍼티 설정이 가능합니다.
interface Person {
name: string;
age?: number;
}
readonly
키워드를 사용하여 읽기 전용 프로퍼티 설정이 가능합니다.
interface Person {
readonly name: string;
age?: number;
}
const person: Person = {
name: "정민교",
// age: 29,
};
person.name = '홍길동' // ❌
interface Person {
readonly name: string;
age?: number;
sayHi: () => void;
}
메서드의 타입을 정의하는 것도 가능합니다.
위는 함수 표현식으로 메서드의 타입을 정의했지만 호출 시그니처로 정의할 수도 있습니다.
interface Person {
readonly name: string;
age?: number;
sayHi(): void;
}
함수 표현식으로 메서드 타입을 정의하면 오버로딩 구현이 불가능합니다.
따라서 호출 시그니처를 이용해서 메서드 타입을 정의하고 오버로딩을 구현해야 합니다.
interface Person {
readonly name: string;
age?: number;
sayHi(): void;
sayHi(a: number): void;
sayHi(a: number, b: number): void;
}
인터페이스 확장이랑 한 인터페이스가 다른 인터페이스를 상속하도록 하는 문법입니다.
다른 인터페이스를 상속하기 때문에 다른 인터페이스의 프로퍼티도 상속합니다.
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;
}
위 타입들은 Animal
타입을 기반으로 추가적인 프로퍼티를 가지고 있는 형태입니다.
즉 Animal
타입이 가지는 name
, age
프로퍼티를 모두 공통적으로 가지고 있으며 각 추가 프로퍼티를 가지고 있습니다.
이런 중복 코드는 좋지 않은 형태입니다.
Animal
타입의 프로퍼티가 하나 바뀌면 Dog
, Chicken
, Cat
인터페이스의 각 프로퍼티도 변경해야 합니다.
이런 문제는 인터페이스 상속(확장)으로 해결할 수 있습니다.
interface Animal {
name: string;
color: string;
}
interface Dog extends Animal {
breed: string;
}
interface Cat extends Animal {
isScratch: boolean;
}
interface Chicken extends Animal {
isFly: boolean;
}
extends
키워드로 인터페이스를 확장(상속)할 수 있습니다.
이렇게 함으로써 Animal
타입은 각 타입의 슈퍼 타입이 됩니다.
interface Animal {
name: string;
color: string;
}
interface Dog extends Animal {
name: "doldol"; // 타입 재 정의
breed: string;
}
위와 같이 확장과 동시에 프로퍼티를 재정의하여 타입을 정의할 수 있습니다.
주의할 점은 반드시 Dog
타입에서 재정의한 프로퍼티는 Animal
타입의 프로퍼티의 하위 타입이어야 합니다.
interface Animal {
name: string;
color: string;
}
interface Dog extends Animal {
name: number; // ❌
breed: string;
}
위와 같이 Dog
타입의 name
프로퍼티를 number
타입으로 재정의 하는 것은 불가능합니다.
type Animal = {
name: string;
color: string;
};
interface Dog extends Animal {
breed: string;
}
위와 같이 타입 별칭으로 정의한 Animal
타입을 확장하도록 인터페이스를 정의할 수 있습니다.
interface DogCat extends Dog, Cat {}
const dogCat: DogCat = {
name: "",
color: "",
breed: "",
isScratch: true,
};
여러 개의 인터페이스를 확장하는 것도 가능합니다.
타입 별칭은 동일한 스코프 내에서 중복된 이름으로 선언할 수 없습니다.
하지만 인터페이스는 가능합니다.
type Person = {
name: string;
};
type Person = { ❌
age: number;
};
interface Person {
name: string;
}
interface Person { // ✅
age: number;
}
위와 같이 중복으로 선언한 인터페이스들은 겱구 하나로 합쳐져서 다음과 같은 인터페이스가 됩니다.
interface Person {
name: string;
age: number;
}
이러한 기능을 선언 합침(Declaration Merging) 이라고 부릅니다.
interface Person {
name: string;
}
interface Person {
name: number;
age: number;
}
동일한 이름의 인터페이스를 중복 선언할 때 같은 이름의 프로퍼티를 다른 타입으로 정의하면 오류가 발생합니다.