[TS] 타입스크립트의 기초(2) - Class와 상속, 그리고 interface와 type의 차이점

2022. 7. 5. 04:00·Learning-Log/Computer Science
728x90
320x100
 

[TS] 타입스크립트의 기초(1) - type 키워드 및 Type에 대한 이해

TypeScript(TS)는 기본적으로 Javascript complier다. TS는 Strongly type 언어이고 JS에서 발생할 수 있는 오류를 미리 감지하고 경고해준다. 따라서 TS에서 오류가 없다면 JS에서도 오류가 없을 것이다. 이것은

xpectation.tistory.com

 

TS에서는 Java나 C계열 언어에서의 Class와 거의 동일한 Class문법을 명시적으로 지원한다.


하지만 오해하지 말자. JS도 객체지향적 언어이다. class 키워드를 통한 문법 대신 prototype을 통해 객체지향성을 구현했을 뿐.
TS로 Class 를 작성한뒤 컴파일 하면, ES6에서 도입된 JS의 Class 문법으로 코드가 변환되는데, ES6의 Class 문법은 사실 prototype을 활용하면서도, prototype 문법을 감추어 둔 함수일 뿐이다.

public : 클래스의 코드블럭 밖에서도 접근 가능한 프로퍼티 = 인스턴스에서 쓸 수 있음. (기본값)
private : 클래스의 코드블럭 안에서만 접근 가능한 프로퍼티 = 인스턴스에서 쓸 수 없음. 
protected : 클래스 및 클래스를 상속받은 자식 클래스의 코드블럭 안에서만 접근 가능한 프로퍼티 = 인스턴스에서 쓸 수 없음.

참고로 private이나 protected를 통해 접근을 차단하는 것을 정보은닉이라고 부른다.
Class에 관해서는 OOP(Object Oriented Programming)에 관해 다룰 때 좀 더 깊게 얘기할 예정.

TS에서는 abstract class(추상적 범주, 추상적 클래스)도 제공된다.

추상적 범주는 extends를 통해 확장의 대상이 되며, 추상적 범주를 확장한 범주를 상속받은 범주(클래스)라 부른다. 다만, abstract class를 통해 바로 인스턴스를 생성할 수는 없다. 말 그대로 추상적 범주이기 때문. 추상적이라는 의미를 인스턴스로 구체화 될 수 없다는 뜻으로 정리해도 좋다.
추상적 범주에 정의된 public method는 해당 범주를 상속받은 범주에서 접근가능하다. 따라서 상속 받은 범주에서 구체화된 인스턴스에서도 당연히 접근 가능하다.
 

또한, abstract method도 제공된다.

아래의 코드를 통해 정의할 수 있다. 코드를 보면 알 수 있듯, call signature만 정의하기 때문에 진정한 의미에서의 코드는 존재하지 않는다. 그래서 abstract이다. 참고로 abstract method가 존재하는 클래스를 통해 생성된 인스턴스는 반드시 abstract method를 구현해야만 한다.
abstract <call signature>

readonly 옵션도 제공된다. 만약 public 메서드에 readonly 옵션을 달아둔다면, 인스턴스에서 접근이 가능하지만, 직접적으로 인스턴스의 값을 수정하지는 못하게 막을 수 있다.

하지만 추상적 범주는 치명적인 단점이 있다.

추상적 범주라는 개념은 JS에는 존재하지 않는 개념이지만, 범주(Class, 클래스)라는 개념은 존재하기 때문에 TS가 JS로 컴파일 되는 과정에서 결국 일반적인 Class로 선언된다는 점이다. 따라서 예기치 못한 문제점들이 발생할 수 있다.

이를 보완하기 위해 쓰이는 것이 바로 interface (혹은 type)이다.

interface는 JS로 컴파일되지 않고 TS내에서만 존재한다. 따라서 abstract class와 달리 JS에서는 TS단계에서 어떤 interface 코드를 작성했는지 알 수 없고 접근할 수도 없게 된다는 점에서 결과적으로 갖게되는 JS코드도 가벼워지고, 예기치 못한 런타임 에러를 방지할 수 있다. 

abstract class를 확장 할 때는 extends 를 썼지만, interface 혹은 type를 Class에 상속 받기 위해서는 implements를 쓴다는 것이 다를 뿐이다.

abstract class Snack {
  constructor(
    public sort: string
  ) { }
  getSort() {
    console.log(this.sort)
  }
}

class Nacho extends Snack {
  constructor(
    public sort: string,
    public price: number
  ) { super(sort) }
  getPrice() {
    console.log(`${this.price}원`)
  }
}

const doritos = new Nacho("nacho", 1500)

doritos.getSort()		// "nacho"
doritos.getPrice()		// "1500원"

참고로 super 문법은 JS 문법이다.

Class의 확장시에는 부모 Class에 존재하는 constructor의 모든 요소를 구현해야하는데(애초에 그래서 상속이다. '부모님의 빚은 안 받고 재산만 받을래요' 가 가능한 상속법은 없다.) 이 구현과정을 도와주는 일종의 short-cut이다.
우리는 super()을 통해서 부모에 있던 코드를 다시 무의미하게 복붙하는 일을 피할 수 있다.

interface Snack {
  sort : string
  getSort():void
}

class Nacho implements Snack {
  constructor(
    public sort: string,
    public price: number
  ) { }
  getSort() {
    console.log(this.sort)
  }
  getPrice() {
    console.log(`${this.price}원`)
  }
  
}

const doritos = new Nacho("nacho", 1500)

doritos.getSort()		// "nacho"
doritos.getPrice()		// "1500원"

마찬가지로 interface의 경우에도 요소를 생략할 수 없다. 위 예제에서는 Nacho Class에서 sort, getSort()가 반드시 구현되어야 한다.

interface와 같이 TS에서 JS로 컴파일 되지 않는 것이 하나 더 있다.

그것은 바로 이전 포스팅에서 설명한 (그리고 바로 앞에 얘기한) type 키워드를 통해 생성된 Type 이다.
이전 포스팅에서도 언급했듯, type 키워드를 통해서는 결국 특정 Type 및 구조를 특정 변수에 할당하게 되므로, 이는 JS로 컴파일되는 과정에서 사라지게 된다. Type은 형식만 지녀서 그 실질이 없기 때문이다.

한마디로, abstract class 보다는 interface나 type이 좀 더 권장된다는 뜻이다. 이제 그럼 interface와 type을 비교해보자.

 

300x250

 

type CarType = {
	name : string
}

const carTyped : CarType = {
	name : 'Camaro'
}
interface CarInterface {
	name : string
}

const carInterfaced : CarInterface = {
	name : 'Camaro'
}

이처럼 위 두 방법은 매우 유사하지만 표현적인 측면에서 가장 큰 차이점은 바로 = 의 유무이다.
다시 한 번 말하지만, type은 기본적으로 변수 선언 키워드(var, let, const) 와 동일한 작용을 한다는 점을 기억하자. 그러면 변수에 뭔가를 할당해주면서 '=' 을 쓰지 않는 것이 더 이상하다. 

또한, 바로 이 점 때문에 type 혹은 interface를 확장할 때의 문법도 달라진다.

type CarType = {
	name : string
}

type CarType2 = CarType & {
	cc : number
}

const carTyped : CarType2 = {
	name : 'Camaro',
	cc : 6200
}

CarType은 일종의 Type 전용 변수이므로, 이를 CarType2에 상속 받고 싶다면, 연산자를 통해 합집합으로 처리하는 것이다.

반면, interface는 좀 더 Class 문법스러운 방법을 지원한다.

interface CarInterface {
	name : string
}

interface CarInterface2 extends CarInterface {
	cc : number
}

const carInterfaced : CarInterface2 = {
	name : 'Camaro',
	cc : 6200
}

게다가 interface 의 경우 type과 달리 기존에 선언된 interface를 다시 선언하면서 내용을 추가할 수도 있다.

반면, (귀에 피가 날 것 같아도 어쩔 수 없다.) type은 변수 선언 키워드와 동일한 작동 메커니즘을 가지고 있으므로, 사실상 TS차원에만 존재하는 하나의 변수(정확히는 상수 const 개념)이다. 따라서 이미 선언된 변수에 새로운 값을 할당할 수 없기 때문에 아래와 같은 코드는 에러가 뜨게 된다.

type은 TS세계에만 존재하는 const (Type) 선언 키워드이다!!! 귀에 딱지가 앉으리라!!!!

 

자 그렇다면 둘 중에서 도대체 뭘 써야할까?

일반적인 TS프로젝트 그리고, 커뮤니티에서는 객체나 클래스의 Type을 지정할 때는 interface 를 쓸 것을 권장한다.
참고로 TS 공식 문서에서는 자유롭게 선택할 수 있다고 안내되어 있긴 하다.

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Learning-Log > Computer Science' 카테고리의 다른 글

[NestJS] NestJS, 한 번 빠지면 벗어날 수 없는 마성의 늪(1) : 소개  (0) 2022.07.11
Tistory의 코드블럭을 이쁘게 만들어보자 : 코드블럭 테마 (highlight.js) 적용방법  (2) 2022.07.06
[TS] 타입스크립트의 기초(1) - type 키워드 및 Type에 대한 이해  (0) 2022.07.05
[TS] 타입스크립트 Generic에 대한 이해와 활용  (0) 2022.07.01
[NPM] 패키지 설치시 더 이상 '--save' 플래그를 입력하지 않아도 되는 이유  (0) 2022.06.24
'Learning-Log/Computer Science' 카테고리의 다른 글
  • [NestJS] NestJS, 한 번 빠지면 벗어날 수 없는 마성의 늪(1) : 소개
  • Tistory의 코드블럭을 이쁘게 만들어보자 : 코드블럭 테마 (highlight.js) 적용방법
  • [TS] 타입스크립트의 기초(1) - type 키워드 및 Type에 대한 이해
  • [TS] 타입스크립트 Generic에 대한 이해와 활용
Xpectation
Xpectation
理
    반응형
    250x250
  • Xpectation
    자기실현적 기대
    Xpectation
  • 전체
    오늘
    어제
    • 전체보기 (214)
      • Thinking-Log (42)
        • 인간에 관한 생각 (22)
        • 사회현상에 관한 생각 (9)
        • 말씀에 관한 생각 (4)
        • 기타 잡념 (7)
      • Trading-Log (8)
        • 주식 잡념 (9)
      • Learning-Log (104)
        • Computer Science (70)
        • Economics (21)
        • Law (1)
        • ETC (12)
      • Review-Log (43)
        • 食思味 (13)
        • 聽思聰 (6)
        • 視思明 (12)
        • IT 제품, 전자기기 (7)
        • 게임 (0)
        • 기타 (5)
      • Creating-Log (5)
        • 주방 (0)
        • 서재 (5)
        • 기타 (0)
      • Photo-Log (3)
        • 사진 일기 (3)
      • 미분류 (0)
  • 블로그 메뉴

    • 홈
    • 방명록
    • 태그
  • 링크

    • 티스토리 홈
  • 공지사항

  • 인기 글

  • 태그

    클래식음악
    주식
    ASMR
    딥러닝
    수면유도
    티스토리챌린지
    마인드위즈Pro
    매매일지
    경제학
    오블완
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
Xpectation
[TS] 타입스크립트의 기초(2) - Class와 상속, 그리고 interface와 type의 차이점
상단으로

티스토리툴바