TIL 22-06-15

thisisyjin·2022년 6월 15일
0

TIL 📝

목록 보기
64/113

TypeScript

🙋‍♂️ Ref Lecture

  • Interface
  • Polymorphism

interface

추상 클래스

  • 추상 클래스는 다른 클래스가 가져야 할 프로퍼티와 메서드를 명시해주는 청사진과 같은 역할.
abstract class User {
  constructor(
  	protected firstName:string,
    protected lastName:string,
  ) {}
  abstract sayHi(name:string):string
  abstract fullName():string
}

class Player extends User {
  fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
  sayHi(name:string) {
    return `Hello ${name}! My name is ${this.fullName()}`;
  }
}
  • 추상 클래스를 사용한 경우, new 키워드로 인스턴스를 생성할 수 없다.
  • 반드시 추상 클래스에 명시한 추상 메서드를 구현(implement) 해줘야 한다.
  • ❗️ 자바스크립트는 추상화(abstract)의 개념이 없어서 컴파일시 일반 클래스로 변경된다.

🔻 JS 코드

"use strict";
// 🔻 User은 new 키워드로 인스턴스를 생성할 수 없으므로 아래 constructor 코드는 불필요하다.
class User {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
class Player extends User {
    fullName() {
        return `${this.firstName} ${this.lastName}`;
    }
    sayHi(name) {
        return `Hello ${name}! My name is ${this.fullName()}`;
    }
}

위와 같이 User은 그저 청사진 역할이라 객체를 생성하지 못한다.
-> 그럼에도 constructor 메서드가 존재하는데, 이는 불필요한 코드라고 볼 수 있다.

이럴 때 우리는 추상화를 interface로 진행한다!

✅ interface는 컴파일시 JS로 바뀌지 않고 사라지기 때문에 가볍다.

interface

  • object나 class의 모양을 정해줌
    interface User {
     firstName: string,
     lastName: string,
     sayHi(name:string):string
     fullName():string
    }

class Player implements User {
constructor(
public firstName:string,
public lastName:string,
){}
fullName() {
return ${this.firstName} ${this.lastName};
}
sayHi(name) {
return Hello ${name}! My name is ${this.fullName()};
}
}


> - **클래스가 인터페이스 구현**시 `implements` 키워드 사용.
> - 객체에 인터페이스 적용시 	`:` 으로 작성하면 됨.

 
interface를 사용한 경우 프로퍼티를 모두 구현해야 한다.

🔻 JS 코드
``` js
"use strict";
class Player {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    fullName() {
        return `${this.firstName} ${this.lastName}`;
    }
    sayHi(name) {
        return `Hello ${name}! My name is ${this.fullName()}`;
    }
}

아까는 인스턴스를 만들수도 없는 쓸모없는 User 클래스가 Js 코드에 존재했었지만,
이번에는 인터페이스를 사용했으므로 위와 같이 짧은 코드가 되었다. 👍

🔻 또한 하나 이상의 인터페이스를 상속받을 수 있다.

interface User {
  // 내용
}

interface Human {
  // 내용
}

class Player implements User, Human {
  constructor(){}
}

클래스를 타입으로 쓸 수 있듯이, 인터페이스도 타입으로 사용할 수 있다.

interface User {
  firstName: string,
  lastName: string,
  sayHi(name:string):string
  fullName():string
}

function makeUser(user:User): User {
  return {
      ...
  }
}

makeUser({
  firstName: 'yjin',
  lastName: 'lee',
  fullName: () => "yjin lee"
  sayHi: (name) => "string" 

Recap

  • 추상 클래스 vs interface
    class에서 인터페이스를 구현하려면 implements를 써야 함.
    class에서 (추상)클래스를 구현하려면 extends를 써야 함.
  • interface vs type
    type은 모든 값 가능.
    interface는 객체만 가능.

interface는 확장시 클래스처럼 extends를 사용함.

type과 interface는 모두 class에 상속해서 쓸 수 있음

type PlayerA = {
  firstName: string
}

interface PlayerB {
  firstName: string
}

class User implements PlayerA {
  constructor(public firstname:string){}
}  // type도 implements로 상속함

class User implements PlayerB {
  constructor(public firstname:string){}
} 

🙋‍♂️ 언제 어떤 것을 사용할까?

  • object의 모양을 알려줄 때는 - Interface
  • 나머지 상황에서는 - Type Aliases
    +) 확장을 해야하는 상황에서는 인터페이스가 편리함.

Polymorphism

= 다형성

  • 다른 모양의 코드를 가질 수 있게 함.

  • 제네릭(Generic)을 사용함. -> type의 placeholder 역할.

  • concrete 타입을 사용하기 애매한 경우 generic으로 placeholder type을 지정하고, 때가 되면 concrete type이 되게 함.

Example

// 이미 Storage라는 인터페이스가 존재함. (localStorge API를 위해)
interface SStorage<T> {
  [key:string]: T
}

class LocalStorage<T> {
  private storage: SStorage<T> = {}
  
  set(key:string, value:T) {
    this.storage[key] = value;
  }
  remove(key:string) {
    delete this.storage[key]
  }
  get(key:string):T {
    return this.storage[key]
  }
  clear() {
    this.storage = {}
  }

}

const stringStorage = new LocalStorage<string>()
const numberStorage = new LocalStorage<number>()

<T>는 generic(제네릭)으로, 이는 인터페이스에게 물려줄수도 있다.

LocalStorage 에서 <T>를 선언한 후,
SStorage(=인터페이스)에도 붙여주어 해당 값을 물려줄 수 있다.
-> SStorage 에서는 받아온 제네릭을 사용한다.

profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글