본문 바로가기

TypeScript

클래스 - 기초

class NothingImportant {}


이렇게 정의된 클래스는 new키워드를 이용해 인스턴스화(instantiation) 할 수 있다. 클래스는 인스턴스를 찍어내는 일종의 틀로 생각할 수 있다.

    const nothingImportant: NothingImportant = new NothingImportant()

생성자

constructor 키워드를 사용해 클래스 생성자(class constructor)를 정의할 수 있다. 만약 어떤 클래스가 생성자를 정의하지 않았다면, 본문이 비어있는 함수가 생성자로 사용된다. (constructor() {} )객체 생성자와 유사하게, 클래스 생성자를 통해 클래스 인스턴스가 생성될 때 실행될 로직을 정의할 수 있다.

    class BarkingDog {
      constructor(barkingSound: string) {
        console.log(`${barkingSound}!`);
      }
    }

    const barkingDog: BarkingDog = new BarkingDog('월'); // 월!

속성

객체 속성과 유사하게 클래스 인스턴스도 속성(property)를 가질 수 있다. 클래스 내에서는 속성엔 this 키워드를 이용해 접근 가능하다. 모든 클래스 속성은 이름: 타입 꼴의 속성 선언(property declaration)을 통해 타입을 표기해주어야 한다.

    class Triangle {
      // 속성 선언
      vertices: number;
      constructor() {
        // 속성 할당
        this.vertices = 3;
      }
    }
    const triangle: Triangle = new Triangle();
    console.log(triangle.vertices); // 3
```
--strictPropertyInitialization 옵션
앞서 --strict 컴파일러 옵션이 켜진 환경을 가정한다 언급한 적 있다.
--strict 옵션은 --strictPropertyInitialization 옵션을 포함한다. 
이 옵션이 켜진 환경에선 undefined 를 포함하지 않는 클래스 속성이 
반드시 속성 선언 또는 생성자, 두 장소 중 한 곳에서 초기화 되어야 한다.
생성자와 속성 선언 두 곳 모두에서 초기화되지 않는 경우 속성 값이 undefined일 가능성이 존재한다. 
따라서 타입스크립트는 그 정보가 타입에 포함되어 있지 않다면 타입 에러를 낸다. 다음 예시를 보자.

class User {
private password: string;
}
// error TS2564: Property 'password' has no initializer and is not definitely assigned in the constructor.

password는 속성 선언에서도, 
생성자에서도 초기화되지 않고 있으므로 접근되는 시점에 undefined 일 수 있다. 
이 값은 string 타입이 아니므로 타입 에러가 발생하는 것이 합당하다. 
이 에러를 없애기 위해선 두 가지 방법이 존재한다.

실제 상황을 정확히 반영하기 위해 password을 선택 속성으로 선언한다.
즉 password: string 를 password?: string (또는 password: string | undefined) 로 변경한다.
password가 undefined여서 문제가 생길 일이 없다고 확신한다면, 
속성 이름 뒤에 느낌표(!)를 붙여 확정적 할당 단언(definitive assignment assertion)을 제공할 수 있다.
즉 password: T를 password!: T로 변경한다. 이 경우 컴파일러는 password의 초기화 체크를 건너뛴다.
  ```

속성 기본값

함수의 기본 인자와 유사하게 클래스 속성에도 기본값을 제공할 수 있다

    class Triangle {
      vertices: number = 3;
    }
    const triangle: Triangle = new Triangle();
    console.log(triangle.vertices); // 3

읽기 전용 속성

readonly 키워드를 사용해 읽기 전용 속성을 정의할 수 있다.

속성 선언 또는 생성자 외의 장소에서는 읽기 전용 속성에 값을 할당 할 수 없다.

    class Triangle {
      readonly vertices: number;
      constructor() {
        this.vertices = 3;
      }
    }
    const triangle: Triangle = new Triangle();
    triangle.vertices = 4;
    // error TS2540: Cannot assign to 'vertices' because it is a constant or a read-only property.

이 때, 읽기 전용 속성은 `--strictPropertyInitialization 옵션` 여부와 무관하게 반드시 속성 선언 또는 생성자에서 초기화되어야 한다. 읽기 전용이라는 정의 자체에 의해 그 두 곳 이외에선 할당 자체가 불가능하기 때문이다. 만약 둘 중 어느 곳에서도 초기화 되지 않았다면 에러가 발생한다.

    class Triangle {
      vertices: number;
      readonly angles: number[];
      constructor() {
        this.vertices = 3;
      }
    }
    // error TS2564: Property 'angles' has no initializer and is not definitely assigned in the constructor.

메소드

    class BarkingDog {
      barkingSound: string;

      constructor(barkingSound: string) {
        this.barkingSound = barkingSound;
      }

      bark(): void {
        console.log(`${this.barkingSound}!`);
      }
    }
    const barkingDog: BarkingDog = new BarkingDog('월');
    barkingDog.bark(); // 월!

'TypeScript' 카테고리의 다른 글

클래스 - 심화 - 스태틱 멤버  (0) 2019.10.30
클래스 - 확장  (0) 2019.10.30
인터페이스  (0) 2019.10.30
열거형  (0) 2019.10.30
인터섹션 타입  (0) 2019.10.30