TypeScript 7장 - 러닝 타입스크립트(6)
포스트
취소

TypeScript 7장 - 러닝 타입스크립트(6)

TypeScript

image

Part.2

chapter.8 클래스

8.1 클래스 메서드

  • 매개변수 타입에 타입이나 기본값을 지정하지 않으면 any타입을 기본으로 갖는다.
  • 메서드를 호출하려면 허용 가능한 수의 인수가 필요하고, 재귀 함수가 아니라면 대부분 반환 타입을 유추할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    class Greeter {
      greet(name: string) {
        console.log(`${name}, do your stuff`);
      }
    }
    
    new Greeter().greet("Miss Frizzle"); // OK
    
    new Greeter().greet();
    // Error: Expected 1 argument, but got 0
    
    • string 타입의 단일 필수 매개변수를 갖는 greet클래스 메서드를 가진 Greeter 클래스를 정의한 코드이다.
    • 클래스 생성자는 매개변수와 관련하여 전형적인 클래스 메서드처럼 취급되며, 타입스크립트는 메서드 호출 시 올바른 타입의 인수가 올바른 수로 제공되는지 확인하기 위해 타입 검사를 수행한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    class Greeted {
      constructor(message: string) {
        console.log(`As I always say: ${message}`);
      }
    }
    
    new Greeted("take chances, make mistakes, get messy");
    
    new Greeted();
    // Error: Expected 1 arguments, but got 0.
    
    • Greeted 생성자는 message: string으로 매개변수가 제공되어야 한다.

8.2 클래스 속성

  • 클래스의 속성을 읽거나 쓰려면 클래스에 명시적으로 선언해야 한다.
  • 클래스 속성은 인터페이스와 동일한 구문을 사용해 선언하며, 속성 이름 뒤에는 선택적으로 타입 애너테이션이 붙는다.
  • 타입스크립트는 생성자 내의 할당에 대해 그 멤버가 클래스에 존재하는 멤버인지 추론하려고 하지 않는다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    class FieldTrip {
      destination: string;
    
      constructor(destination: string) {
        this.destination = destination; //OK
        console.log(`We're going to ${destination}`);
    
        this.nonexistent = destination;
        // Error: Property 'nonexistent' does not exist on type 'FieldTrip'.
      }
    }
    
    • destination은 string으로 명시적으로 선언되어 있어 FieldTrip 클래스인 인스턴승 할당되고 접근할 수 있다.
    • 클래스가 nonexistent 속성을 선언하지 않았기 때문에 생성자에서 this.nonexistent 할당은 허용되지 않는다.
    1
    2
    3
    4
    5
    
    const trip = new FieldTrip("planetarium");
    
    trip.destination; // OK
    trip.nonexistent;
    // Error: Property 'nonexistent' does not exist on type 'FieldTrip'.
    
    • 클래스 속성을 명시적으로 선언하면 클래스 인스턴스에서 무엇이 허용되고 허용되지 않는지 이해할 수 있다.
    • 클래스 인스턴스가 사용될 때, 코드가 trip.nonexistent와 같은 클래스 인스턴스에 존재하지 않는 멤버에 접근하려고 하면 타입 오류를 발생시킨다.
8.2.1 함수 속성
  • 자바스크립트에는 클래스의 멤버를 호출 가능한 함수로 선언하는 두 가지 구문이 있는데, 멤버 이름 뒤에 괄호를 붙이는 메서드 접근 방식이 있다.
  • 또한 값이 함수인 속성을 선언하는 방식도 있다.

    1
    2
    3
    4
    5
    
    class WithMethod {
      myMethod() {}
    }
    
    new WithMethod().myMethod === new WithMethod().myMethod; // true
    
    • myFunction(){}과 같이 멤버 이름 뒤에 괄호를 붙여 메서드에 접근할 수 있다.
    • 메서드 접근 방식은 함수를 클래스 프로토타입에 할당하므로 모든 클래스 인스턴스는 동일한 함수 정의를 사용한다.
    1
    2
    3
    4
    5
    
    class WithProperty {
      myProperty: () => {};
    }
    
    new WithProperty().myProperty === new WithProperty().myProperty; // false
    
    • 값이 함수인 속성을 선언하는 방식을 사용하면, 클래스 인스턴스를 가리켜야 하는 화살표 함수에서 this 스코프를 사용하여 클래스 인스턴스당 새로운 함수를 실행하는 시간과 메모리 비용 측면에서 유용하다.
    • 위의 함수 표현식은 단일 속성을 갖고 있는 () => void 타입이다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    class WithPropertyParameters {
      takesParameters = (input: boolean) => (input ? "Yes" : "No");
    }
    
    const instance = new WithPropertyParameters();
    
    instance.takesParameters(true); // OK
    
    instance.takesParameters(123);
    // Error: Argument of type 'number' is not assignable to parameter of type 'boolean'.
    
8.2.2 초기화 검사
  • 엄격한 컴파일러 설정이 활성화된 상태에서 타입스크립트는 undefined 타입으로 선언된 각 속성이 생성자에서 할당되었는지 확인한다.
  • 엄격한 초기화 검사는 클래스 속성에 값을 할당하지 않는 실수를 예방할 수 있어 유용하다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    class WithValue {
      immediate = 0;
      later: number; // OK(Constructor에서 할당)
      myBeUndefined: number | undefined; // OK(undefined가 되는 것이 허용됨)
      unused: number;
      // Error: Property 'unused` has no initializer
      // and is not definitely assigned in the constructor.
    
      constructor() {
        this.later = 1;
      }
    }
    
  • 엄격한 초기화 검사가 없다면, 타입 시스템이 undefined 값에 접근할 수 없다고 할지라도 클래스 인스턴스는 undefined 값에 접근할 수 있다.
  • 엄격한 초기화 검사가 수행되지 않으면 올바르게 컴파일되지만, 결과 자바스크립트는 런타임 시 문제가 발생한다.

    1
    2
    3
    4
    5
    6
    
    class MissingInitializer {
      property: string;
    }
    
    new MissingInitializer().property.length;
    // TypeError: Cannot read property 'length' of undefined
    
  • 클래스 생성자 다음에 클래스 속성을 의도적으로 할당하지 않는 경우가 있을 수도 있다.
  • 엄격한 초기화 검사를 적용하면 안 되는 속성인 경우에는 이름 뒤에 !를 추가해 검사를 비활성화하도록 설정한다.
  • 이렇게 하면 타입스크립트에 속성이 처음 사용되기 전 undefined 값이 할당된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    class ActivitiesQueue {
      pending: string[]; // Ok
    
      initialize(pending: string[]) {
        this.pending = pending;
      }
    
      next() {
        return this.pending.pop();
      }
    }
    
    const activities = new ActivityQueue();
    
    activities.initialize(["eat", "sleep", "learn"]);
    activities.next();
    
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.