Backend 언어/JS&TS

[이펙티브 타입스크립트] 몽키 패치보다는 안전한 타입을 사용하기

민초부 2022. 3. 1. 14:56
반응형

> 43장 몽키 패치보다는 안전한 타입을 사용하기 

  • 몽키 패치란? 
    • 런타임 중에 property object를 직접적으로 수정하는 일련의 작업들을 말한다. (JS 기준)
    • 이러한 몽키 패치는 일반적으로 안티 패턴 (비효율적이거나 비생산적인 패턴)으로 인식된다. 가끔 옛 버전 기준으로 적용해야하는 케이스를 위해 커스터마이징을 하는 용도로 사용하는 것을 제외하고는 당연히 이러한 패치들은 런타임 중에 특정 시점에 적용되는 것인데도 불구하고 전역 변수로 적용이 되기 때문에 다른 코드에도 영향을 주고 부작용을 발생시킬 수밖에 없음
    • (아래 케이스 기준으로) 그리고 이렇게 처리하면 Typescript에서는 type에 반영이 안 되기 때문에 type checker에서 걸려 에러가 난다.
    • 예시
<JS>
window.monkey = 'Tamarin';
document.monkey = 'Howler';


<TS>
document.monkey = 'Howler'
	// ~~~~~~ Property 'monkey' does not exist on type 'Document'
  • 그리고 any 처리를 해서 넣는다 하더라도 any를 사용함에 따라 Typechecker에서 빠져 TS를 사용하는 의미가 없어진다. 
    (그래서 TS에선 보통 Lint가 이러한 prototype을 아예 건들지 못 하게 한다.)
(document as any).monkey = 'Tamarin' 
// any로 선언했기 때문에 monkey라는 property 선언 가능하다. 

// 하지만 아래 monkey property값을 가져올 때 항상 any로 선언해야하고 
// 오타 등의 이유로 없는 property 값을 가져오려 할때 나중에 런타임 중에 에러가 터져야 알 수 있다.
const value = (document as any).monkey // Tamarin
const value2 = (document as any).monky // undefined로 값이 할당




String.prototype.double = function double(): string {
      return this.concat(this as string);
}

console.log('Hello'.double());
// HelloHello
  • 위의 double 예시처럼 하면 컴파일 에러는 나지만 생성된 JS파일을 실행시키면 정상적으로 돌아간다. 

 

>>>> 몽키 패치를 대신하여 TS에서 처리할 수 있는 방법이 있다. 

 

  • Interface의 Augmentation(보강)을 사용하기 
    • 말그대로 type의 property를 보강하는 것이라 생각하면 되는데 사용하는 것에 Global Augmentation Module Augmentation이 있다. (type-safe-monkey-augmentation.ts 파일 참조)
  • 더 구체적인 타입 단언문 선언하기
    • 예시를 보면 쉽다.
 interface MonkeyDocument extends Document {
 	monkey: string;
 }
 
(document as MonekyDocument).monkey = 'Test';

 

반응형