타입스크립트 접근제한자(public, protected, private)
2021-11-10
자바스크립트에는 마땅히 Class 내부의 값을 은닉화를 할 수 있는 방법이 없었다.
다행히 타입스크립트에는 접근 제한자(Access modifier)인 public, protected, private를 지원하며, 이를 통해 외부에서 특정 메서드나 프로퍼티에 접근 범위를 지정할 수 있다.
public
public은 어디에서나 접근할 수 있으며 생략 가능한 default 값이다.
class Hello {
name: string
constructor(name: string) {
this.name = name
}
// public 생략 가능
public greet() {
console.log(`hi! ${this.name}`)
}
}
const hello = new Hello('kmj')
hello.greet() // output: 'hi! kmj'
name을 선언해주기 위해서 꽤나 많은 양의 코드를 작성해야 하는데, 이를 constructor에서 한 번에 선언할 수 있다.
class Hello {
constructor(public name: string) {}
// 생략
}
protected
protected는 해당 클래스 혹은 서브클래스의 인스턴스에서만 접근이 가능하다.
// 1. 해당 클래스에서 접근
class Hello {
constructor(public name: string) {}
greet() {
console.log(`hi! ${this.name}, log: ${this.test()}`)
}
protected test() {
return 'test'
}
}
const hello = new Hello('kmj')
hello.greet() // output: 'hi! kmj, log: test'
// 2. 서브클래스에서 접근
class Hi extends Hello {}
const hi = new Hi('howdy')
hi.greet() // output: 'hi howdy, log: test'
단, 서브클래스에서 protected로 된 값을 public으로 오버라이딩한다면 해당 값은 public으로 취급된다.
class Hi extends Hello {
test() {
return 'override'
}
}
const hi = new Hi('howdy')
hi.greet() // output: 'hi howdy, log: override'
const test = hi.test()
console.log(test) // output: 'override'
오버라이딩할 경우, 상위클래스의 return 타입과 같아야 한다 그렇지 않으면 에러를 반환한다.
private
private는 해당 클래스의 인스턴스에서만 접근 가능하다.
class Hello {
constructor(private name: string) {}
}
const hello = new Hello('kmj')
hello.name // Property 'name' is private and only accessible within class 'Hello'.
위의 예시에서 name을 가져오려하려면, 위와 같은 에러가 뜬다.
그리고 서브클래스에서 name을 public으로 바꾸어주려고 해도 에러가 뜬다.
class Hi extends Hello {
constructor(public name: string) {
super(name)
}
// Class 'Hi' incorrectly extends base class 'Hello'.
// Property 'name' is private in type 'Hello' but not in type 'Hi'.ts(2415)
}
Caveats
하지만 private와 protected로 지정한 값들이 항상 보호되는 것이 아니라, key 값으로는 접근이 가능하다.
const hello = new Hello('kmj')
console.log(hello['name']) // output: 'kmj'
따라서 온전히 보호하기 위해서는 다른 장치가 필요하다. (추후 보충)
readonly
만약 정말 수정되면 안되는 값이 있다면, readonly 접근자를 활용해야 한다.
class Hello {
readonly hey: string = 'Hey'
constructor(private name: string) {}
}
const hello = new Hello('kmj')
console.log(hello.hey) // output: 'Hey'
hello.hey = 'test' // Error: Cannot assign to 'hey' because it is a read-only property.
추후 추가할 내용
- getter, setter
참고