Extending an interface
Extending a type via intersection
vanilla js를 많이 다루지는 않지만 이론적으로 알고 있는 extending 개념은 react class component 정도 에서나 사용해 본 경험이 있다.
기본적으로 기본 legacy porp을 물려받아 class를 확장하는데 사용하는 extending 개념을 type을 확장하는데 그대로 적용해줄 수 있다.
기왕 복습하는거 super도 알아보자.
class Polygon {
constructor(height, width) {
this.name = 'Polygon';
this.height = height;
this.width = width;
}
sayName() {
console.log('Hi, I am a ', this.name + '.');
}
}
class Square extends Polygon {
constructor(length) {
this.height; // 참조오류가 발생합니다. super가 먼저 호출되어야 합니다.
// 여기서, 부모클래스의 생성자함수를 호출하여 높이값을 넘겨줍니다.
// Polygon의 길이와 높이를 넘겨줍니다.
super(length, length);
// 참고: 파생 클래스에서 super() 함수가 먼저 호출되어야
// 'this' 키워드를 사용할 수 있습니다. 그렇지 않을 경우 참조오류가 발생합니다.
this.name = 'Square';
}
get area() {
return this.height * this.width;
}
set area(value) {
this.area = value;
}
}
핵심만 요약하자면 위에서 선언한 Polygon class는 sayName()이라는 method를 가지고 있다.
밑의 Square는 Polygon class를 extends 해서 사용하기로 하고 자신만의 class props를 추가하여 사용할 수 있다. 여기에서 Square는 sayName() method를 사용할 수 있는가?
답은 아니오다.
super를 사용하면 상위 클래스에 접근할 수 있는데 사용법은 크게 두가지이다.
super(); = 이는 상위 클래스(extends 한)를 생성한다.
super.(method) = 이는 상위 클래스의 method를 호출하여 사용한다.
여기에 한 가지 더 static도 알아두자.
정적 키워드인 static은 class가 instance를 찍어내지 않아도 바로 접근이 가능하게 한다.
class ClassWithStaticMethod {
static staticProperty = 'someValue';
static staticMethod() {
return 'static method has been called.';
}
}
console.log(ClassWithStaticMethod.staticProperty);
// output: "someValue"
// 원래라면 인스턴스 생성후 해당 인스턴스에 접근해야 정상
console.log(ClassWithStaticMethod.staticMethod());
// output: "static method has been called."
서론이 길었지만 뭐 어떤가 이해하는데 도움이 되었다면 그것으로 충분한 것이다.
아무튼 위의 내용을 이해했다면 아래 내용은 자연스럽게 보이게 된다.
interface Animal{ name: string }
interface Bear extends Animal{
honey:boolean
}
const bear=(bear:Bear)=>{
console.log({name:bear.name});
console.log({honey:bear.honey});
}
bear({name:'gomgom',honey:true});
Animal, Bear 모두 객체 타입에 담겨있고 {key_1:type , key_2:type}
의 형태로, 함수를 호출하는 경우에도 위 처럼 호출해주면 된다.
type alias도 확장하는 방법이 있는데 아래와 같다.
type Animal={
name:string;
}
type Bear=Animal &{
honey:boolean; // Boolean 이 intellisense에 뜨는데 뭐가 다른지는 모르겠다.
}
const bear=(bear:Bear):void=>{
console.log('name: ',bear.name)
console.log('honey: ',bear.honey)
}
bear({name:'cocacola',honey:false});
위 코드에서 주의할 점이 있는데
bear({name:'cocacola'})
이처럼 하나의 인자만 넘겨서는 안된다는 것이다.
type Bear=Animal &{
honey:boolean;
}
먼저 선언한 type alias인 Animal과 & { 현재 선언하는 타입 }
으로 함께 묶여있다.
따라서 and 연산을 받으므로 이는 모두 선언을 해주어야 에러가 뜨지 않는다.