Lsiron
Type Script 에서 외부 자바스크립트 파일을 사용할 때 (declare, ambient module / local module) 본문
Type Script 에서 외부 자바스크립트 파일을 사용할 때 (declare, ambient module / local module)
Lsiron 2024. 7. 17. 21:28Type Script에서 외부 자바스크립트 파일을 사용하려면 어떻게 해야할까?
TypeScript를 사용하기 전에 JavaScript 만 사용할 때 nodemailer 라이브러리 같은 외부 자바스크립트 파일을 이용하기 위해 import를 사용하던 경우가 있었을 것이다.
하지만 TypeScript에서는 외부 타입스크립트 파일이 아닌 외부 자바스크립트 파일을 가져와서 사용하려면 declare 키워드를 이용하여 타입을 지정 해 주어야한다.
( 자바스크립트 파일에는 당연히 타입이 지정되어 있지 않기 때문에 생으로 가져와서 사용하면 에러가 발생한다. )
declare 키워드는 JavaScript 라이브러리 또는 이미 컴파일된 다른 TypeScript 코드의 타입 정보를 TypeScript 컴파일러에게 알려주는 데 유용하다. - declare 키워드를 쓰면 가져와서 사용하기 좋다는 뜻이다.
declare ?
declare 키워드는 외부에서 이미 정의된 변수나 함수 그리고 타입을 재정의 할 수 있다.
간단하게 export와 import의 경우로 먼저 알아보자.
// export.js
let age = 28;
let lsiron = 'siron';
// import.ts
declare let age :number;
console.log(age + 1); // 29 출력
export.js 파일에서 아무 타입도 지정이 안된 변수 age를 import.ts 파일에서 declare 키워드를 사용하여 number 타입으로 지정해주고, 출력하였더니 마치 import.ts 파일에서 age 변수를 선언한 것 처럼 정상 작동을 한다.
이 처럼, declare 키워드는 TypeScript에게 특정 변수, 함수, 클래스, 모듈 등이 외부에 존재한다는 것을 알리는 역할을 한다.
아직까진 말이 너무 어렵다. 그렇다면 위 예시의 경우 declare 키워드를 사용한 의미는 무엇일까?
바로 age라는 변수가 export.js 파일에 정의되어있는데 import.ts 파일에서 또 age 변수를 정의하긴 싫으니까 잠깐 정의를 해 달라는 뜻이다.
사용법은 declare를 선언 해 주고 우측에 변수나 함수 또는 타입을 적어주면 된다.
js파일 변수를 가져다 쓸 때 타입에러나 변수가 없다는 에러가 발생한다면 declare 키워드를 사용하면 된다.
declare는 실제 구현이 존재하지 않으며, 컴파일된 JavaScript 코드에는 포함되지 않기 때문에 declare 가 적용된 코드들은 js로 변환되지 않는다.
( 컴파일러를 통해 ts파일이 js로 변환이 되면 declare 기능은 작동하되, declare 글자가 사라진다. )
이 처럼 자바스크립트로만 작성된 외부 라이브러리들을 쓸 때 타입스크립트 버전이 없다면 직접 declare로 타입작성하면 된다.
참고로, tsconfig.json 안에 allowJs 옵션을 true로 설정하면 TypeScript는 JavaScript 파일을 자동으로 포함하고 컴파일할 수 있게 된다. ( 이는 리액트 같은 프로젝트에서 유용하다. )
declare 키워드와 함께 사용하는 방식은 크게 두 가지로 나뉘는데 바로 글로벌 선언과 모듈 선언이다.
글로벌 선언
글로벌 선언은 전역 스코프에서 사용되는 변수나 함수 등을 선언하는 데 사용된다.
// globals.d.ts
declare let jQuery: (selector: string) => any;
위 예제는 전역 환경에서 사용할 jQuery라는 전역 변수를 선언하고 있다.
declare let 구문을 사용하여 TypeScript 컴파일러에게 jQuery가 어떤 형태의 전역 변수인지를 알리며, jQuery 함수가 받는 매개변수 selector는 문자열이고, 반환하는 값은 any 타입임을 명시하고 있다.
이렇게 선언된 변수는 모든 TypeScript 파일에서 접근할 수 있는 전역 변수로서 사용될 수 있다.
( 위 에서 declare 사용법 다룬게 글로벌 선언이다. )
// app.ts
let element = jQuery('#myElement');
element.show();
TypeScript는 jQuery 함수를 사용할 때 selector 매개변수가 문자열임을 인지한다. 예를 들어, element에는 show 메서드가 있다는 것을 알고 있다.
모듈 선언
모듈 선언은 특정 모듈이 존재한다고 TypeScript에게 알리는 방식이다. 이는 주로 외부 라이브러리의 타입 정보를 정의할 때 사용된다.
// myLibrary.d.ts
declare module "myLibrary" {
export function myFunction(): void;
}
이 예제는 모듈로 정의된 myLibrary에 대한 타입을 선언한다.
declare module 구문을 사용하여 "myLibrary"라는 문자열 모듈 이름을 가진 모듈을 정의하고 있으며, 이 모듈은 myFunction이라는 함수를 내보내는 것으로 정의되어 있다.
이 선언은 myLibrary 모듈이나 패키지를 사용할 때 TypeScript에서 해당 모듈의 형태와 내부 함수에 대한 타입 정보를 제공한다.
따라서 두 예제는 다음과 같은 차이점을 가지고 있다.
- 전역 변수 vs 모듈: globals.d.ts의 경우 전역 환경에서 사용할 변수나 함수를 선언하는 데 사용되며, 모든 TypeScript 파일에서 접근 가능하다. 반면, myLibrary.d.ts의 경우는 모듈을 정의하고 해당 모듈이 내보내는 함수나 변수의 타입을 선언하는 데 사용된다. 모듈은 일반적으로 파일 단위로 정의되며, 모듈을 사용하는 코드에서는 모듈 이름과 함께 import 구문을 사용하여 가져올 수 있다.
- 선언의 목적: globals.d.ts는 주로 외부 라이브러리나 프레임워크의 전역 변수를 TypeScript에서 사용할 수 있도록 타입을 지정하는 데 사용된다. 반면, myLibrary.d.ts는 내부 모듈이나 라이브러리의 인터페이스를 정의하여 사용자가 해당 모듈을 사용할 때 타입 안정성을 유지할 수 있도록 돕는다.
Ambient Module ?
Type Script 에는 이상한 특징이 하나 있다. 바로 ts 파일들 끼리는 export나 import를 하지 않아도 변수나 타입등이 공유가 된다.
왜냐하면 일반적인 ts 파일에 입력한 변수와 타입들은 모두 전역변수 취급을 받기 때문이다. 이렇게 전역으로 쓸 수 있는 파일을 글로벌 모듈 즉, Ambient Module 이라고 한다. ( TypeScript에서 name 변수명을 사용할 수 없는 이유 )
// export.js
let age = 28;
let lsiron = 'siron';
// import.ts
let age :number; // 가능하다
console.log(age + 1); // 가능하다
이렇게 되면 한 ts 파일에서 age 변수명으로 변수를 선언했을 때 다른 ts 파일에서 다른 용도로 age 변수명을 사용하려면 재정의를 해야한다.
이런 재정의를 막기 위해서는 local module로 만들어주어야 하는데, local module로 만들어주는 방법은 ts파일에 export나 import 키워드를 삽입하는 것 이다.
이 말은 즉, 한 ts 파일이 다른 ts 파일들에 영향이 끼치는 것을 막고싶으면 export 키워드를 강제로 추가하면 된다.
// export.js
export {};
let age = 28;
let lsiron = 'siron';
// import.ts
let age :number; // 불가능하다
console.log(age + 1); // 불가능하다
위 예시처럼 export.ts 파일에 export를 넣어주면 local module이 됨으로써 export.ts 파일은 더 이상 ambient module 이 되지 않으며, 다른 ts 파일에서 사용할 수 없다.
만약 export나 import 키워드를 넣어 local module로 만든 파일에서 갑자기 ambient module을 사용하고 싶어진다면?
declare global {} 문법을 사용하여 아래와 같이 만들면 된다.
// export.js
export {};
let age = 28;
declare global {
let Iron: string;
}
// import.ts
let age :number; // 불가능하다
console.log(age + 1); // 에러 발생!!
let lsiron:Iron = 'siron' // 가능하다
console.log(lsiron); // siron 출력
보통 declare global {} 문법은 로컬 모듈에서 타입변수 혹은 인터페이스를 전역으로 사용하고 싶을 때 써준다.
참조 : 코딩애플
'언어 > Type Script' 카테고리의 다른 글
Type Script 의 implements ? (0) | 2024.07.18 |
---|---|
Type Script 에서 d.ts 파일이란? 그리고 외부 js 라이브러리 가져오기 (0) | 2024.07.18 |
Type Script 의 tuple type 이란? (0) | 2024.07.17 |
Type Script 의 Generic 이란? (1) | 2024.07.17 |
Type Script 에서의 export , import 그리고 namespace (0) | 2024.07.16 |