프론트엔드 개발/Typescript

this

하이고니 2023. 2. 21. 22:54

파도 파도 끝이 없는 this의 세계..

 

'this' 일반적으로 메서드를 요청하는 기능을 한다.

 

class Department {
  name: string;     // 키 이름만 정의하고 키가 갖게될 타입 정의

  constructor(n: string) {  // new 로 인스턴스 만들 때 인자를 받는다.
    this.name = n;
  }
  
  describe() {
    console.log('Department: ' + this.name);
  }
}

const accounting = new Department('Accounting');
accounting.describe();

const accountingCopy = { describe: accounting.describe };
accountingCopy.describe();	// Department: undefinded

 

위 경우에서 describe 메서드를 요청하는 것은 accountingCopy 다.

accountingCopy에서 describe를 호출하기 때문이다. 따라서 this . 앞에 있는 accountingCopy 참조한다.

 

그런데 accountingCopy는 name 속성이 없는 객체이기 때문에 this.name에 접근하면 에러가 발생한다.

this name 속성이 있는 객체를 참조하지 않기 때문에 name 정의되지 않는다.

 

이 문제를 해결하기 위해 this를 호출하는 describe 메서드에 매개변수를 추가할 수 있다. (this)

이는 타입스크립트가 이해할 있는 특별한 명령이다.

 

 

this라는 매개변수를 추가하면, 값을 전달하지 않고도 여전히 describe를 호출할 수 있다.

대신 타입스크립트는 this가 무엇으로 참조되는지 알아야 한다. 그러므로 매개변수 this에 타입을 할당해야 한다.

 

타입에 Department 클래스를 할당해주면 accountingCopy.describe() 호출문에 오류가 발생한다.

그 이유는 accountingCopy가 describe를 호출하지만 Department의 인스턴스는 아니기 때문이다.

 

this가 위반된 것이다. 따라서 리터럴 객체에 name 속성을 추가하여 타입 안정성을 지켜야 한다.

 

class Department {
  name: string; 

  constructor(n: string) {
    this.name = n;
  }
  
  describe(this: Department) {
    console.log('Department: ' + this.name);
  }
}

const accounting = new Department('Accounting');
accounting.describe();

const accountingCopy = {name: 'DUMMY', describe: accounting.describe };
accountingCopy.describe();