웹개발 및 최신 테크 소식을 전하는 블로그, 웹이즈프리

HOME > js

[Typescript] 2편. 타입스크립트 클래스 생성 및 interface

Last Modified : 2022-01-19 / Created : 2022-01-17
7,699
View Count

타입스크립트를 사용하여 클래스(class)를 생성하고 사용하는 방법에 대하여 알아봅니다.



# 타입스크립트에서의 클래스 사용하기

타입스크립트에서도 자바스크립트와 동일하게 클래스를 선언하고 사용할 수 있습니다. 먼저 간단하게 Site라는 이름의 클래스를 하나 만들어 봅니다.

class Site {
}

아무것도 없는 빈 클래스를 하나 생성하였습니다. 이제 클래스에 새로운 프로퍼티를 선언해보겠습니다.
class Site {
  no: number;
}

class 내부에 no, url 두 개의 프로퍼티를 선언하였습니다. 하지만 타입스크립트에서는 다음과 같이 에러를 발생합니다.

"Property 'no' has no initializer and is not definitely assigned in the constructor"


클래스 내부의 프로퍼티가 초기화나 생성자 없이 사용되었다는 에러입니다. 위와 같이 클래스에서 프로퍼티를 사용하는 경우 해당 타입과 함께 초기화 구문이 필요합니다. 위의 에러를 수정하기 위해 아래와 같이 타입과 값을 함께 사용 할 수 있습니다.
class Site {
  no: number = 0;
}

Site 클래스의 no는 숫자타입이면서 초기 0의 값으로 설정되었습니다. 다른 방법으로 아래와 같이 constructor 내부에 no를 선언하여도 에러는 해결됩니다.
class Site {
  no: number;

  constructor() {
    this.no = 0;
  }
}

이와 같이 타입스크립트에서 클래스를 사용하는 경우 내부의 프로퍼티(변수)는 타입 선언 및 초기화에 필요한 과정이 있어야만합니다.

이번에는 프로퍼티 아래에 메소드를 추가해봅니다.
class Site {
  no: number;

  constructor(no: number) {
    this.no = no;
  }

  getNo() {
    return this.no;
  }
}

새로운 getNo() 메소드가 Site 클래스에 추가되었습니다.


! 클래스에서 새로운 인스턴스 생성하기

이제 위의 Site 클래스를 사용하여 새로운 인스턴스 Webisfree를 만들어보려고 합니다. 인스턴스를 생성하려면 new 키워드를 사용해야죠 ~ 새로운 no, url 프로퍼티를 가질 수 있도록 아래와 같이 작성하였습니다.
class Site {
  no: number;
  url: string;

  constructor(no: number, url: string) {
    this.no = no;
    this.url = url;
  }
}

const Webisfree = new Site(1, 'webisfree.com');

Site 클래스로부터 인스턴스 Webisfree가 만들어졌습니다. 아래와 같이 프로퍼티의 no, url 값들을 가진 것도 확인 할 수 있습니다
Webisfree.no
// 1

Webisfree.url
// 'webisfree.com'


프로퍼티에 readonly 사용하기
타입스크립트의 modifier인 readonly는 말 그대로 읽기전용을 나타내며 사용할 경우 값을 변경할 수 없게 됩니다. 만약 위의 no 프로퍼티를 읽기전용으로 사용하려면 아래와 같이 코드를 수정합니다.
class Site {
  readonly no: number;
  url: string;

  constructor(no: number, url: string) {
    this.no = no;
    this.url = url;
  }
}

const Webisfree = new Site(1, 'webisfree.com');

url 값은 변경이 가능하지만 readonly 값을 가진 no를 수정하려고 하면 다음과 같이 에러가 발생합니다.
Webisfree.no = 2;
// 에러 발생. Readonly이므로 값 변경이 불가함

이처럼 readonly의 경우 해당 프로퍼티의 값을 수정할 수 없게 됩니다.


interface(인터페이스) 사용하기
타입스크립트에는 interface가 존재합니다. interface는 클래스나 객체에서 사용할 프로퍼티와 메소드를 클래스 외부에 따로 분리하여 선언할 수 있는 방법입니다. 이렇게 선언한 interfaceimplements를 사용하여 클래스나 객체에 사용할 수 있습니다.

간단한 예제를 만들어봅니다. 앞서 만들었던 Site 클래스를 interface를 사용해서 ISite를 만들어보겠습니다. interface의 이름은 클래스나 객체 이름의 앞 글자를 대문자로 사용하거나 또는 I를 붙여서 사용하기도 합니다.
interface ISite {
  no: number;
}

이제 앞에서 만들었던 Site 클래스에 위의 ISite 인터페이스(interface)를 사용해보도록 하겠습니다.
class Site implements ISite {
  no: number;

  constructor(no, url) {
    this.no = no;
  }
}

위와 같이 interface는 사용할 프로퍼티와 타입을 분리하여 사용할 수 있는 방법입니다. 이처럼 interface를 사용할 경우 동일한 데이터를 여러 번 사용할 때 반복해서 프로터티나 타입 등을 선언하지 않아도 된다는 장점이 있습니다,

이번에는 interface를 객체와 함수에 사용한 예제입니다.
// 인터페이스 만들기
interface ISite {
  no: number;
}

// 객체에 인터페이스 사용하기
const mySite: ISite = {
  no: 1
};

// 함수에 인터페이스 사용하기
const getSiteNo = (site: ISite) => {
  return site.no;
};

여러개의 인터페이스 적용, 다중 인터페이스 적용
참고로 하나가 아닌 여러 개의 interface를 사용하는 것도 가능합니다. 아래는 두 개의 interface를 적용한 모습니다.
class Site implements ISite, IFavorite {
}


인터페이스의 확장, extends
인터페이스가 다른 인터페이스를 상속 받는 것처럼 확장할 수 있습니다. 예를들어 B라는 인터페이스가 A 인터페이스를 확장하여 적용하는 것이 가능합니다. 간단한 예제를 먼저 알아봅니다.
interface ISite {
  no: number;
  url: string;
}

interface IFavorite extends ISite {
  id: string;
}

인터페이스 IFavorte은 id에 추가로 ISite의 no, url가 확장되어 사용하게 되었습니다. 즉 아래와 같이 Site 클래스에 적용하는 경우 no, url, id 모두 필요하게 됩니다.
class Site implements IFavorite {
  no = 0;
  url = 'webisfree.com';
  id = 'abc';
}

여기까지 interface를 사용하는 방법을 알아보았습니다.


! Optional 프로퍼티 사용하기

 아래에서 Site 클래스는 ISite 인터페이스를 사용하고 있습니다. 그런데 interface가 만약 아래와 같이 no, url 두 개의 프로퍼티를 가지고 있으나 실제 class에서는 하나만 선언하고 있는 경우 에러가 발생하게 됩니다.
interface ISite {
  no: number;
  url: string;
}

class Site implements ISite {
  no: number;

  constructor(no: number) {
    this.no = no;
  }
}

에러의 원인은 interface가 가진 url은 사용되지 않았기 때문에 발생하게 됩니다. 이처럼 interface에 사용되고 선언된 부분은 클래스와 반드시 일치하여야 합니다. 만약 url을 실제 클래스에서 사용할 지 안 할 지 모르는 경우라면 Optional 프로퍼티를 사용해야 합니다.

이제 interface에 url을 선택적으로 사용할 수 있도록 Optional 프로퍼티 표기인 ? 기호를 추가해줍니다.
interface InterfaceSite {
  no: number;
  url?: string;
}

위 interface의 url 바로 뒤에는 ? 기호를 사용하여 Optional 프로퍼티임을 표기하였습니다. 이제 타입스크립트에서 더 이상 에러가 발생하지 않습니다.


여기까지 타입스크립트의 클래스를 선언하고 사용하는 방법에 대하여 알아보았습니다. 다음에는 클래스를 상속 하는 방법 등을 추가적으로 알아보겠습니다.

Previous

자바스크립트 배열 메소드 every() 알아보기

Previous

[typescript] 타입스크립트 클래스의 확장, 접근 제한자 사용 방법 알아보기