인터페이스는 기본적으로 type alias와 비슷하지만
객체의 형태를 묘사하는 데에 사용된다. 오직 객체에만 사용된다.
다양한 프로퍼티, 혹은 메서드를 포함하고 있는 객체에 사용된다
interface Person {
name: string;
age: number;
}
const sayHappyBirthday = (person: Person) => {
return `Hey ${person.name}, congrats on turning ${age}!`;
}
sayHappyBirthday({name: 'Jerry', age: 42});
interface 키워드를 사용하고 인터페이스의 이름이 들어가는데 등호 = 를 사용하지 않음.
그리고 프로퍼티의 이름과 해당하는 타입이 들어간다
이미 배운 type alias와 같이 readonly, 선택적 프로퍼티도 똑같이 작동한다
메서드를 프로퍼티로 넣을 수도있다.
interface Person {
readonly id: number; // Person.id는 고칠수 없다. 읽기전용.
first: string;
last: string;
nickname?: string; // ? 를 붙이면 해당 프로퍼티는 없어도 오류표시가 뜨지 않는다.
sayHi: () => string; // 아무것도 받지 않고 문자열을 반환하는 메서드.
}
const thomas: Person = {
first: "Thomas",
last: "Hardy",
nickname: "Tom",
id: 21837,
sayHi: () => { // 아무것도 받지 않고 문자열을 반환하는 메서드.
return "Hello!";
},
};
인터페이스에 포함된 메서드의 프로퍼티들을 지정할수도 있다.
interface Product {
name: string;
price: number;
applyDiscount(discount: number): number; // 숫자 프로퍼티를 넣으면 숫자를 반환하는 메서드.
}
const shoes: Product = {
name: "Blue Suede Shoes",
price: 100,
applyDiscount(amount: number) { // 할인율을 넣으면
const newPrice = this.price * (1 - amount); // 할인된 가격을 계산하여
this.price = newPrice;
return this.price; // 반환하는 메서드.
},
};
인터페이스는 한번 선언하고도 이후에 다시 열어서 새로운 프로퍼티를 추가할 수 있다.
interface Dog { // 일단 인터페이스를 선언하고
name: string;
age: number;
}
interface Dog { // 또 같은 인터페이스를 선언하면 대체되는 것이 아니라 합쳐진다.
breed: string;
bark(): string;
}
const elton: Dog = { // 전부 충족해야 오류표시가 뜨지 않음.
name: "Elton",
age: 0.5,
breed: "Australian Shepherd",
bark() {
return "WOOF WOOF!";
},
};쇼
type은 인터페이스와 똑같은 용도로 쓰이지만 위와 같이 하면 두번째로 선언한 것이 첫번째로 선언한 내용을 대체해버린다.
인터페이스의 확장, 즉 타 인터페이스로부터의 상속 기능이 있다
객체 기반 프로그래밍에서 부모 클래스로부터 기능을 상속하는 클래스가 있는것과 유사한 개념이다
interface ServiceDog extends Dog { // 위에서 선언한 Dog 인터페이스에서 상속받아서
job: "drug sniffer" | "bomb" | "guide dog"; // job이라는 프로퍼티만 추가한다.
}
const chewy: ServiceDog = { // Dog 인터페이스의 프로퍼티 + job까지 충족해야 한다.
name: "Chewy",
age: 4.5,
breed: "Lab",
bark() {
return "Bark!";
},
job: "guide dog",
};
그런데 상속을 받을때 하나에서만 상속받아야 하는 것은 아니다. 여러개에서 상속 받을수도 있다.
interface Human {
name: string;
}
interface Employee {
readonly id: number;
email: string;
}
interface Engineer extends Human, Employee { // Human과 Employee 두군데서 상속 받아서
level: string;
languages: string[]; // level과 languages 프로퍼티를 추가한다
}
const pierre: Engineer = { // Human과 Employee의 프로퍼티들에 level,languages까지 충족해야 함.
name: "Pierre",
id: 123897,
email: "pierre@gmail.com",
level: "senior",
languages: ["JS", "Python"],
};
리터럴 타입 등을 묘사하는 데에 사용할 수 없다
type Color = "red" | "blue"
이런 리터럴 타입은 인터페이스로는 표현할수 없다
타입은 그렇게 하면 대체되어 버린다
타입은 extends를 이용한 상속이 아닌 &을 사용한 교차(intersection) 타입을 사용해야 한다