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 프로퍼티를 추가해주면 에러는 없어집니다.
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); } }
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
으로 생각합니다.