[Typescript] declare, prototype

Falcon·2021년 7월 7일
1

typescript

목록 보기
1/6
post-thumbnail

🎯 Goal

  • declare 키워드 용도를 알고 쓸 수 있다.
  • prototype 을 언제 써야할 지 알고 쓸 수 있다.

🤔 문제 상황

타입스크립트에서 prototype 키워드를 사용하여 메소드를 정의하면
인식이 되지 않는다.

String.prototype.isEmpty = function isEmpty() : boolean {
    return this.length === 0 || !this.trim();
}

const str : string = 'ss';
//console.assert(str.isEmpty(), errorMessage);


console.assert(str.isEmpty(), errorMessage);
                   ^
//🚫 TypeError: str.isEmpty is not a function🚫

🔑 해결 방안

declare 키워드를 사용한다.

declare 는 언제쓰나?

declare is used to tell the compiler "this thing (usually a variable) exists already, and therefore can be referenced by other code, also there is no need to compile this statement into any JavaScript"

  • d.ts 같은 타입스크립트 타입 정의 파일이 존재하지 않는 자바스크립트 라이브러리를 타입스크립트 내에서 사용하고자 할 때
    declare var myLibrary;
    // myLibrary 라는 타입(@types) 정의가 없는 자바스크립트 라이브러리를 타입스크립트 전역에서 사용하고자 할 때
  • 정의를 다른곳에 미리 해두고 마음껏 다른 모듈에서 사용할 때 (ex. global scope)

⚽ 예제

프로젝트 전역에서 쓸 전역 타입 정의 파일을 생성한다.

Prototype.d.ts

declare global {
    interface String {
        isEmpty() : boolean
    }
}

export {}

prototypeTest.ts

import './Prototype'; // 최초 1회는 타입이 정의된 모듈을 import 해야한다.

String.prototype.isEmpty = function isEmpty() : boolean {
    return this.length === 0 || !this.trim();
}

const str : string = 'ss';
const errorMessage : string = 'this is not empty!';
const strObject = new String('ss');

// 정상 작동한다.
console.assert(str.isEmpty(), errorMessage);
// ✅ Assertion failed: this is not empty!
console.assert(strObject.isEmpty(), errorMessage);
// ✅ Assertion failed: this is not empty!

⚠️ declare 키워드로 선언된 부분은 javascript 로 transpile 되지 않는다.

prototypeTest2.ts

import {strObject} from "./prototypeTest";
// 비록 1번 테스트 예제로부터 불러왔지만 
// global variable 로 전역 선언되어있기 때문에
// prototype method 사용이 가능하다.
console.dir(strObject);// [String: 'ss']
console.assert(strObject.isEmpty(), 'ㄱㅣ모르딲딲') // Assertion failed: ㄱㅣ모르딲딲

⚠️ IDE Error

// TS2339: Property 'union' does not exist on type 'Set'.

Typescript 는 .ts 을 만나면 .d.ts 파일을 동일 디렉토리 내에서 자동으로 찾는 메커니즘이있다.

tsconfig.json

{
    "compilerOptions": {
     // .. 중략 ..
    "typeRoots": [
      "node_modules/@types",
      "src/types"
    ]
   },
      "include" [
      	"src/*"
      ],
     "exclude": [
		"node_modules",
	    "dist",
      // 💡 여기서 제외된다는 것은 컴파일 대상이 아니라는 뜻
	    "test"
      ]
  },
  // .. 생략 ..
}

exclude 는 컴파일 대상에서 제외시킬 파일 목록
include 는 컴파일 대상에 포함시킬 목록 (default: ** == 모든 파일 컴파일)

include < exclude 우선순위 (exclude 가 더 큼)

✍️ 한줄 요약

라이브러리를 사용할 때, @types (타입스크립트 정의파일) 을 때 혹은
typescript에서 prototype 메소드 정의시 declare 키워드를 사용하자.

사실 요새 @types 파일을 지원하지 않는 라이브러리는 드물고, 아래 구문으로 커버가 가능한 상황이 훨씬 많다.

import * as '모듈 내에서 쓸 namespace 이름' from <'자바스크립트 라이브러리명';
// 이걸로 충분하다.

🔗 Reference

profile
I'm still hungry

0개의 댓글