TypeScript - 클래스와 인터페이스 (2) Interfaces

Younkyum J·2022년 7월 9일
0

TypeScript

목록 보기
8/8
post-thumbnail

인터페이스 | Interface

타입과 인터페이스

인터페이스는 Type과 비슷한 구조이다.
우선, player라는 타입을 만든다고 가정해보자.

type Player -= {
  nickname: string,
  healthBar: number
}

const onve : Plyaer = {
  nickname: "onve",
  healthBar: 10
}

아니면 이런 방식의 선언도 가능하다.

type Food = string;

또한, 타입이 특정 옵션들만 가지도록 만들 수도 있다.

type Tema: "red" | "blue" | "yellow"

type Player = {
  nickname: string,
  team: Team // 팀은 오직 red, blue, yellow만 가능하다.
}

그렇다면 인터페이스는 어떨까?
우선 type을 interface로 바꿔도 어떤 문제도 발생하지 않는다.

interface Player {
  nickname: string,
  team: Team
}

하지만 인터페이스는 오직 한가지의 역할만 가지고 있다.
바로 오브젝트의 모양을 결정해주는 것이다.
따라서 타입보다는 인터페이스를 쓸 때 사용하는 방식이 제한된다.

interface Team: string // Error

인터페이스의 사용

User interface를 만들어보자

interface User {
  name: string
}

interface Player extends User {
}

const onve: Player = {
  name: "onve"
}

타입과 사용법이 모두 똑같다. "="만 제외하면 모두 동일하다.




클래스와 인터페이스

추상 클래스를 생각해보자.

abstract class User = {
  constructor(
  	protected firstName: string,
    protected lastName: string
  ) {}
  abstract sayHi(name: string): string
  abstract fullNameI(): string
}

class Player extends User {
  fullName() {
    return '${this.firstName} ${this.lastName}'
  }
  sayHi(name: string) {
    return 'Hello ${name}. My name is ${this.fullName()}'
  }
}

이와 같이 추상 클래스와 추상 메소드를 사용할 수 있었다.
하지만 이런 경우, TS가 자동으로 JS로 변경시킬 때 문제가 발생한다.
위의 코드를 JS로 변환시킨다면, 다음과 같다.

class User {
  constructor(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }
}

class Player extends User {
  fullName() {
    return '${this.firstName} ${this.lastName}'
  }
  sayHi(name: string) {
    return 'Hello ${name}. My name is ${this.fullName()}'
  }
}

이와 같이, 원하지 않는 User 클래스가 JavaScript 코드에 들어가게 되는 것이다.

이러한 상황을 막고자, 우리는 interface를 사용할 수 있다.

interface는 가벼워서, JS코드에 들어가지 않고 TS -> JS 단계에서 사라진다.

하지만 interface는 오직 TS에 오브젝트의 모양을 보내주는 역할만 한다.

따라서 abstract class User는 다음과 같이 변한다.

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: string) {
    return 'Hello ${name}. My name is ${this.fullName()}'
  }
}

위의 코드를 보면, interface는 Call Signature를 정해줌으로써 추상 메소드를 넣을 수 있다.

그리고, 한가지 더 중요한 점은 extends 대신 implements를 사용한다는 점이다.

그리고 이때, class내의 내부 프로퍼티는 모두 public으로 지정해야 한다.

implements는 TS에만 있는 것으로써 위의 코드를 JS로 변환할 때 다음과 같이 만들어준다.

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

바뀐 JS 코드가 많이 간단해진것을 알 수 있다.




*본 내용은 노마드코더 "Typescript로 블록체인 만들기"에서 습득한 내용을 바탕으로 재구성한 것 입니다.

profile
기획자입니다. 근데 이제 고양이와 애플덕후와 개발을 곁들인.

0개의 댓글