추상클래스는 추상클래스를 상속할 클래스들의 청사진을 정해주는 느낌이라고 어제 배웠다.
하지만 JavaScript로 컴파일된 모습을 보면.
//in TypeScript
abstract class Exam{
constructor(
public foo:string,
public bar:string
){}
abstract absMethod():string //추상 메서드
}
class Exam2 extends Exam{ //추상클래스로는 인스턴스객체를 만들수없음.
absMethod(){
return 'abstract methods' //추상메서드는 반드시 같이 가야됨(청사진을 따라야지)
}
}
const instanceObj = new Exam2('a','b')
console.log(a.foo)
console.log(a.bar)
//in JavaScript
"use strict";
class Exam {
constructor(foo, bar) {
this.foo = foo;
this.bar = bar;
}
}
class Exam2 extends Exam {
absMethod() {
return 'abstract methods';
}
}
const a = new Exam2('a', 'b');
console.log(a.foo);
console.log(a.bar);
보면 '청사진'의 용도로 만든 추상클래스 Exam이 JS에서 클래스로 떡하니 컴파일되서 파일용량을 차지하고있는걸 볼수있다. 이를 해결할수있는게 interface
Type Alias와는 다른 타입선언 방법. JavaScript에도 룰이 있는것처럼 TypeScript에도 있는데.
Object나 Class의 타입선언은 interface, 그외는 Type Alias로 한다.
그렇다고 한다. interface를 사용해서 추상클래스를 구현하면 JS에선 어떤모습일까?
//in TypeScript
interface User{
firstName:string
lastName:string
sayHi(name:string):string
getFullName():string
}
interface Human{
bloodType:string
}
class Player implements User,Human{
constructor(
public firstName:string,
public lastName:string,
public bloodType:string
){}
sayHi(name:string){
return `my name is ${name}`
}
getFullName(){
return `${this.firstName} ${this.lastName}`
}
}
//in JavaScript
"use strict";
class Player {
constructor(firstName, lastName, bloodType) {
this.firstName = firstName;
this.lastName = lastName;
this.bloodType = bloodType;
}
sayHi(name) {
return `my name is ${name}`;
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
컴파일시 추상클래스(interface로 구현한)는 컴파일되지 않아서 파일용량에 영향을주지 않는걸 볼수있다. 하지만 몇가지 다른점이 있는데
TypeScript공식 문서에서 있는 차이비교를 적어보자면.
// Extending an interface
interface Animal {
name: string
}
interface Bear extends Animal {
honey: boolean
}
//Extending a type via intersections
type Animal = {
name: string
}
type Bear = Animal & {
honey: boolean
}
interface Window {
title: string
}
interface Window {
ts: TypeScriptAPI
}
//기존 interface에 새 fields를 추가하기만 하면 된다.
type Window = {
title: string
}
type Window = {
ts: TypeScriptAPI
}
// Error: Duplicate identifier 'Window'.
// Type은 생성된 이후 유형을 변경할수 없다.
interface SStorage<T>{
[key:string]:T
}
// 이미 JS의 WebStorage API를 위한 Storage인터페이스 정의되어있어서 오버라이드를 막기위해 저렇게 지음
class LocalStorage<T>{ //keypoint
private storage:SStorage<T>;
constructor(){
this.storage = {};
}
set(key:string,value:T){ //keypoint
this.storage[key]=value
}
remove(key:string){
delete this.storage[key]
//javascript의 delete연산자는 객체의 속성을 제거한다(프로퍼티)
}
get(key:string):T{ //keypoint
return this.storage[key]
}
clear(){
this.storage = {};
}
}
const stringsStorage = new LocalStorage<string>()
const booleanStorage = new LocalStorage<boolean>()
booleanStorage.set('key',true)
stringsStorage.set('key','value')
배움은 계속된다..