Class & Interface

박철연·2022년 3월 21일
0

TypeScript 묶음

목록 보기
5/6
post-thumbnail

이번 글에서는 자바스크립트의 class 문법과 타입스크립트를 엮어서 정리하려고 합니다. 추가로 Interface 문법도 간략하게 요약해보겠습니다.

Class와 TypeScript

Class와 필드값

자바스크립트의 class 문법은 비슷한 형태의 객체 데이터를 찍어내는 데 아주 적합합니다.

class 문법에는 모든 자식 객체들이 활용할 수 있는 속성을 공용으로 만드는 기능도 있습니다.

이를 필드라고 보통 이야기하고, 다음과 같은 방식으로 작성합니다.


class Toy {
  color = "red";
}

이런 식으로 작성해주면, Toy라는 클래스로 생성된 모든 객체들은 color="red"를 속성으로 가지게 됩니다. 따로 지정하지 않아도요.

필드 타입 지정하기

우리의 타입스크립트는 기대를 저버리지 않습니다. 필드에도 타입 지정이 가능합니다.

다음과 같은 방식으로 작성하시면 됩니다.

사실 필드의 타입 지정은 제가 "red"라는 문자열을 기입했을 때 부터 암묵적으로 string으로 정해집니다.

그래서 굳이 따로 타입 지정을 하지 않고, 내가 집어 넣고 싶은 형태의 데이터를 작성하면 알아서 타입 지정이 되긴 합니다.

constructor 함수

constructor 함수는 ES6에서 새롭게 등장한 class 관련 문법입니다. 필드처럼 자식 객체들에게 속성을 공유시켜 주는 동시에, 인자를 활용할 수 있게 해줍니다.

말이 약간 복잡한데, 아래 코드 블럭을 참고하시면 이해가 빠르실 것 같습니다.


class Freshman {
  constructor (a){
    this.name = a;
    this.age = 20;
  }
}

new Freshman("Park")

이러면 age는 20이지만 name은 "Park"인 객체가 생성이 되겠죠?

타입스크립트에서 constructor 함수를 정의할 때 주의할 점은, 내가 사용하고자 하는 속성들이 미리 정의되어 있어야 한다는 것입니다. 아니면 에러가 납니다.

위 예시에서는 name과 age가 여기에 해당됩니다. 그래서 아래 코드 블럭처럼 작성해야 오류를 피할 수 있어요.


class Freshman {
  name;
  age;
  constructor (a){
    this.name = a;
    this.age = 20;
  }
}

constructor 함수에서 타입 지정하기

위의 예시에서 우리는 constructor 함수에 들어가는 인자 a가 객체의 name 속성에 들어가게끔 해주었습니다.

코드를 작성하다 보니, name에 문자열을 제외한 다른 타입이 들어가지 못하게 해주고 싶다고 생각했습니다.

애초에 constructor 함수도 함수이기 때문에 그냥 인자에 타입 지정하듯이 하면 간단합니다.


class Freshman {
  name;
  age;
  constructor (a: string){
    this.name = a;
    this.age = 20;
  }
}

추가로, 메서드도 똑같이 타입 지정할 수 있습니다. 함수이기 때문에, 넣을 인자와 결과 값 모두에 타입 지정할 수 있습니다.

Interface

Interface를 소개합니다

interface 문법은 객체의 타입을 좀 더 간편하게 관리할 수 있도록 해주는 문법입니다. 전 게시글에서 다루었던 type 문법과 유사한 부분이 있죠.

실제로 어떻게 활용하는가는 말로 설명보다 코드를 보는 것이 훨씬 쉬울 것 같습니다.

interface Toy { 
  color :string, 
  quantity :number, 
} 

let woody:Toy = { color : 'red', quantity : 2 } 

interface를 써서, Toy를 만들고 woody가 Toy라고 명시해주었습니다.

type 문법과 비슷하죠?

extends의 사용

interface 문법에는 큰 특징 하나가 있는데, 바로 extends라는 키워드를 사용할 수 있다는 것입니다.

우리가 두 가지 interface를 만든다고 가정해보겠습니다.

interface Toy { 
  color :string, 
  quantity :number, 
}
  
interface Robot { 
  color :string, 
  quantity :number,
  isTransforming: boolean,
}

이렇게 Toy와 Robot 두 가지 interface를 만들어 보았습니다. 보시다시피, 두 interface는 color와 quantity를 공유하고 있습니다.

이 때 사용할 수 있는 것이 바로 extends입니다.

interface Toy { 
  color :string, 
  quantity :number, 
}
  
interface Robot extends Toy { 
  isTransforming: boolean,
}

Robot은 Toy의 연장선상이기 때문에, 문자열인 속성 color와 숫자인 quantity를 가지게 됩니다.

거기에 불리언 타입의 isTransforming이 추가되게 됩니다.

이런 식으로 extends 문법을 사용하면 비슷한 형태의 객체를 디테일하게 바꿔서 사용할 수 있을 것입니다.

type 문법과의 차이점

앞서서 interface 문법이 type 문법과 비슷하다고 말씀드렸는데, 이는 extends 문법과 어느 정도 관련이 있습니다.

interface 문법을 활용한 코드를 한 번 살펴보겠습니다.

// interface
interface Animal { 
  name :string 
} 
interface Dog extends Animal { 
  legs :number 
}

// type 문법
type Animal = { 
  name :string 
} 
type Dog = Animal & { legs: number }

interface는 간편하게 extends를 쓸 수 있지만, type은 그런 장치가 없습니다.

그래서 마지막 줄 처럼 다른 타입을 유니언 타입 지정 하듯이 합쳐줘야 합니다.

(다만, 인터섹션 기호인 &를 사용하는 방식은 interface로 선언해도 사용 가능합니다.)

또 타입을 중복 선언했을 때에도 interface 문법과 type 문법은 차이를 보입니다.

interface Animal { 
  name :string 
} 
interface Animal { 
  legs :number 
}

이런 식으로 이름을 중복하면 interface는 알아서 해당 내용을 override 해줍니다.

즉, 위 코드 블럭의 결과로 Animal 타입은 name과 legs 모두를 속성으로 가지게 되겠죠.

type Animal = { 
  name :string 
} 
type Animal = { 
  legs :number 
}

type 문법에서는 타입 이름 중복하면 바로 에러가 뜹니다. 좀 더 엄격하다고 할 수 있겠죠?

그래서 일반적으로는 type 문법을 쓰되, 수정이 자유롭도록 유연한 타입 지정을 하고 싶을 때에는 interface 문법을 쓰면 되겠습니다.

타입 이름 중복도 허용하고, extends로 수정 및 추가도 가능하니까요.

profile
Frontend Developer

0개의 댓글