본문 바로가기
개발/TypeScript

번역 : The Purpose of 'declare' Keyword in TypeScript

by 안뇽! 2022. 12. 4.
반응형

declare를 명확하게 알고있지 않아서 검색하다가 이 글 을 번역하였다.

(이 글에서의 declare사용은 구글맵을 예시로 하고 있지만, 카카오맵을 타입스크립트+리액트에서 사용할 때에도 적용할 수 있다.)

 

원문 : https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

 

Purpose of Declare Keyword in TypeScript

A Detailed Introduction to the Role of TypeScript Declare, so You Are Not a Stranger to *.d.ts Files.

javascript.plainenglish.io

 

아래의 글은 위 원문을 번역한 글(의역)입니다.


타입스크립트에서 declare의 목적

https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

만약 당신이 타입스크립트 프로젝트에서 *.d.ts 를 열어본다면 declare를 본적이 있을 겁니다.
declare 가 어떤것인지 잘 아시나요? 만약 모르신다면 이 글을 읽고나서는 알게 될 것입니다.

 

타입스크립트 프로젝트에서, 당신은 써드파티 JS-SDK를 script tag 형식으로 import 하게 될 수도 있습니다. 가령 구글맵처럼 말입니다.

<script
   src="https://maps.googleapis.com/maps/api/js
   ?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer></script>

위와 같이 선언한 후에는, 당신은 해당 API를 호출할 수 있습니다.

https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

이때 당신이 구글맵 공식문서를 보고 JS-SDK로 제공되는 API를 사용했을지라도,
타입스크립트 컴파일러는 에러를 띄울것입니다.
타입스크립트 컴파일러는 google 이라는 전역 변수를 인식하지 못하기 때문이죠.

그럼 이 문제를 어떻게 해결할 수 있을까요??

 

declare를 사용하여 google이라는 전역변수를 선언하는 것입니다.

 

declare var google: any;

이를 통해 타입스크립트 컴파일러는 전역변수를 인식할 수 있습니다.

 

https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

혹시 이러한 방식을 보고, 혼란스러우신가요??

 

왜 당신은 JSON, Math, Object 같은 전역변수들을 타입스크립트 프로젝트에서 사용할 수 있을까요??

 

타입스크립트는 우리(개발자)를 위해 내부적으로 '선언' 이라는 행위를 하고, 일찍이 언급되었던 전역변수들은 lib.es5.d.ts라는 declaration file에 선언되기 때문입니다.

// typescript/lib/lib.es5.d.ts
declare var JSON: JSON;
declare var Math: Math;
declare var Object: ObjectConstructor;

 

추가로 전역 변수 뿐만 아니라, 전역 함수, 전역 클래스, 전역 enum 등을 선언할때도 declare 를 사용할 수 있습니다.
eval,isNaN,encodeURI,parseInt 등의 함수들도 lib.es5.d.ts에 이미 선언되어 있습니다.

declare function eval(x: string): any;
declare function isNaN(number: number): boolean;
declare function encodeURI(uri: string): string;
declare function parseInt(string: string, radix?: number): number;

실제로 node modules 내부의 lib.es5.d.ts에 선언되어 있는 전역함수들이 있다.

이 때 알고 계셔야 하는 것은, 우리가 declare를 통해 전역함수를 선언할 때, 함수의 기능은 다루지 않는다는 것입니다.
다만 우리는 타입스크립트 컴파일러가 위 전역 JS 함수를 인식할 수 있게 합니다.

 

사실 앞서 보여준 google을 찾지 못하는 이슈에 대한 이러한 솔루션은 상대적으로 폭력적??(relatively violent)입니다.
더 좋은 솔루션은 타입스크립트 웹사이트DefinitelyTyped project(다양한 타입 선언들을 참고할 수 있는 오픈소스) 에서 제공하는 type declaration file serach function을 사용하는 것입니다. 그리고 당신은 더욱 수준높은 서드파티 라이브러리를 통해 타입스크립트 타입 선언을 할 수 있습니다.

https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

위의 정보들을 알게 되었다면, 당신은 npm을 이용하여 모듈을 설치하고 필요한 타입선언을 할 수 있습니다. 만약 당신이 Google Maps와 타입스크립트 사용자를 위한 가이드를 읽었다면, 당신은 type declaration file을 찾았을 것이고, npm 으로 설치할 수 있었을 것 입니다.

npm i -D @types/google.maps

npm package 'foo'의 경우에는 '@types/foo'를 이용할 수 있습니다. 예시로 jquery library와 대응하는 @types/jquery가 있습니다.

 

이제 declare의 또 다른 용례를 살펴봅시다. 우린 client.d.ts안에서 모듈들을 선언하는 수많은 코드들을 볼 수 있습니다.

https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

위 코드에서 우린 css,jpg,ttf 모듈들이 선언된 것을 볼 수 있습니다. 왜 우린 이러한 모듈들이 필요할까요??
만약 위의 모듈들을 선언하지 않았다면 타입스크립트 컴파일러는 위 모듈들을 인식하지 못하고 에러를 뱉기 때문입니다.

https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

또한 각각의 모듈이 하나하나 선언해주는 것(귀찮은작업)을 피하고자, 타입스크립트2.0에서는 wildcard(*) 형식을 지원합니다.

https://javascript.plainenglish.io/purpose-of-declare-keyword-in-typescript-8431d9db2b10

 

 

추가로, 타입스크립트는 declare를 통해 기존에 선언된 타입을 확장하는 것도 가능하게 해줍니다.
예를들면 만약 당신이 axiosVue component instance를 붙히고(add) 싶다면 다음과 같이 작성할 수 있습니다.

import { AxiosInstance } from "axios";
declare module "@vue/runtime-core" {
  interface ComponentCustomProperties {
    $axios: AxiosInstance;
  }
}

그리고 config 객체의 globalProperties 프로퍼티를 사용하여 효과적으로 axios 프로퍼티에 각 컴포넌트 인스턴스를 붙힐 수(add) 있습니다.

import { createApp } from "vue";
import axios from "axios";
import App from "./App.vue";
const app = createApp(App);
app.config.globalProperties.$axios = axios;
app.mount("#app");

마지막으로, 컴포넌트에서 당신은 컴포넌트 내부 인스턴스의 proxy.$axios 프로퍼티를 통해 axios 객체에 접근할 수 있습니다.

import { getCurrentInstance , ComponentInternalInstance} from "vue"
const { proxy } = getCurrentInstance() as ComponentInternalInstance
proxy!.$axios
  .get("https://jsonplaceholder.typicode.com/todos/1")
  .then((response) => response.data)
  .then((json) => console.log(json));

 

 

이 글을 읽고, 난 이미 당신이 declare와 몇가지 실용적인 시나리오를 이해했을 것이라 믿습니다.

만약 타입스크립트에 대한 전문성을 더 키우고 싶다면 Matering TypeScript 시리즈를 놓치지 마세요.

반응형

'개발 > TypeScript' 카테고리의 다른 글

런타임때에 사라지는 타입  (0) 2023.01.18
타입스크립트는 타입 오류가 있어도 컴파일을 한다.  (0) 2023.01.18
Generic  (0) 2022.05.09
Enum  (0) 2022.05.06
Never 타입 -> 내 코드가 뭔가 문제가 있구나!  (0) 2022.02.10