TypeScript - 4

doodream·2021년 6월 17일
0

TypeScript

목록 보기
4/6
post-thumbnail

Class

class Department {
  id: string;
  name: string;

  constructor(id: string, n: string) {
    this.id = id;
    this.name = n;
  }

  decribe(this: Department) {
    console.log(this.name);
  }
}

const testObj = new Department("1", "doo");
testObj.decribe();

const testObjCopy = { decribe: testObj.decribe };
testObjCopy.decribe();// error

위 코드는 단순히 일반적인 자바스크립트의 클래스에 인수 validation 체크만 한 형태입니다.
그런데 Department class의 decribe를 보면 인수에 this를 넣고 Department라고 명시를 해주었습니다. 클래스 안에서 메소드의 경우 this 는 arrow function이 아닌 이상 클래스를 가르킵니다.

따라서 this는 명시 하지 않아도 될 것 같지만 decribe에서 this를 명시한 이유는 클래스의 메소드 코드만 따로 쓰일때 this의 유형에대해 힌트를 주기 위함입니다.

맨아래 testObjCopy에서 decribe라는 프로퍼티에 testObj.decribe 함수를 가르키게 했습니다. 이때 decribe 코드를 가져오게되는데 this: Department라는 힌트는 testObjCopy.decribe가 온전하지 않은 작동을 할 것이라고 알려줍니다.

왜냐면 testObjCopy는 id, name프로퍼티가 없기 때문에 this: Department 유형을 만족하지 못합니다. 따라서 const testObjCopy 객체의 정의에서 id, name 프로퍼티를 추가해주면 에러는 없어집니다.

readonly

class Department {
  //private id: string;
   name: string;

  constructor(private readonly id: string, n: string) {
    this.id = id;
    this.name = n;
  }

  decribe(this: Department) {
    this.id = 2;//error
    console.log(this.name);
  }
}

클래스 안에서 어떠한 프로퍼티는 읽기전용으로 변경이 불가능하게 해야할 경우가 있습니다. 클래스 안에서는 const, let등 변수 선언형태로 프로퍼티가 선언되지 않기 때문에 이러한 경우 타입스크립트에서 readonly 라는 키워드를 사용합니다. 위에서 보면 클래스 내부에서 private id 를 주석처리 한것이 보이는데 이는 읽기전용이므로 id라는 프로퍼티를 할당하기 위해서는 중복되는 readonly 선언을 피하려한 것입니다. this.id = 2 라는 코드에서 바로 에러가 납니다.

class 코드단축

클래스에서 constructor 함수를 선언할때에 class 필드의 변수들에 대해서 this.id = id 이런형태로 선언을 하는 경우가 있습니다. 하지만 필드에 선언을 하지 않고 constructor의 인수에만 선언을 해도 됩니다. 클래스는 함수를 생성하고 constructor 내부의 식을 그대로 함수에 넣은다음 필드부분을 함수의 prototype 프로퍼티로 넣습니다. [[Prototype]] 이 아닙니다. 위 코드를 아래와 같이 필드변수를 없애서 단축시킬수 있습니다.

class Department {
  constructor(private readonly id: string, name: string) {
  }
  decribe(this: Department) {
    this.id = 2; //error
    console.log(this.name);
  }
}

private , protected , public

class Department {
   name: string; // public

  constructor(private readonly id: string, n: string) {
    this.id = id;
    this.name = n;
  }

  decribe(this: Department) {
    console.log(this.name);
  }
}

위 코드에서 보다시피 자바스크립트에서는 private 키워드 대신 변수 앞에 #을 붙여서 사용했습니다. 하지만 typeScript에서는 private 라고 JAVA 처럼 명시를 해줍니다.

이와 마찬가지로 원래 protected 키워드 대신 변수앞에 _ 를 붙여서 개발자들끼리의 바깥에서는 쓰지말자는 관행으로만 약속을 한 경우와 명시를 안한경우 public 으로 생각합니다.

추상클래스

profile
일상을 기록하는 삶을 사는 개발자 ✒️ #front_end 💻

0개의 댓글