-
[패캠] 타입스크립트 문법 - 패키지의 타입 선언 (18/20)Front-end 개발 2024. 2. 1. 17:09
💡 본 타입스크립트 문법 시리즈는,
패캠의 '프론트엔드 웹 개발의 모든 것 초격차 패키지 Online'에 있는 TS 강의 노트이다.현재 수강 중인 패스트캠퍼스(fastcampus, 이하 패캠) 프론트엔드 패키지 강의가 있다.
강사님은 김영웅(Heropy) 님이다.
이 글을 쓰면서 강사님의 블로그에 '한눈에 보는 타입스크립트' 자료가 있다는 것을 알게 됬다... (바보😅)
강의를 듣는데, 강의자료가 없어서 일일이 강사님이 말씀을 따라 적으면서 강의 교안(?), 강의 노트를 작성했다.
혹시나 나처럼 패캠에서 타입스립트(TypeScript)를 수강하는 사람들에게 도움이 되면 좋겠다. 🔥
18. 패키지의 타입 선언
타입스크립트의 모듈 개념에 대해서 알아본다. 외부에서 설치한 패키지의 type 선언이 필요할 때, dts 파일을 따로 만들거나 혹은 definitely typed를 설치하는 개념을 살펴본다.
프로젝트 파일에 VSCode 터미널을 통해 lodash 패키지 설치
npm i lodash
lodash 패키지가 잘 설치되었는지 package.json 파일을 열어서 확인한다. 잘 설치되었다면, 일반 의존성 패키지로 lodash가 들어가 있을 것이다.
{ "name": "ts-test", "version": "1.0.0", "description": "", "scripts": { "dev": "parcel ./index.html", "build": "parcel build ./index.html" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "lodash": "^4.17.21", "parcel": "^2.10.3", "typescript": "^5.3.2" } }
Lodash 는 JavaScript의 인기 라이브러리로 array, number, object, string 등 다양한 형태의 데이터를 쉽게 다룰 수 있게 해준다. 공식 홈페이지에서 Lodash를 사용하는 이유와 사용하기 좋은 상황에 대한 원문 내용은 아래와 같다.
Lodash makes JavaScript easier by taking the hassle out of working with arrays, numbers, objects, strings, etc.Lodash’s modular methods are great for:
- Iterating arrays, objects, & strings
- Manipulating & testing values
- Creating composite functions그런데 lodash를 설치해도 import 키워드로 패키지를 가져오는 코드 라인에서 Error가 발생한다.
import _ from 'lodash' const str = 'the brown fox jumps over the lazy dog.' console.log(_.camelCase(str)) console.log(_.snakeCase(str))
Error의 내용은 lodash라는 패키지, 즉 모듈에 해당하는 선언 파일을 찾을 수 없다는 의미다. lodash라는 패키지는 JavaScript로 만들어져 있다. 그런데 타입스크립트에서 JavaScript 파일을 가지고 오게 되면 당연히 타입스크립트가 원하는 타입 지정이 안되어져 있다. 그렇기 때문에 lodash라는 패키지의 타입 선언이 필요하다.
node_modules 폴더 > lodash 폴더 > package.js 파일을 열어 main 옵션을 확인해보면 main 파일은 lodash.js 라는 이름을 가지고 있는 JavaScript 파일임을 확인할 수 있다. 나의 main.ts 라는 타입스크립트 파일에서 lodash의 JavaScript 파일을 가지고 오다 보니, 타입에 관련된 내용이 없고 Error가 발생한 것이다.
Error 해결방법 : 모듈(패키지)의 타입 선언
src 폴더에 원하는 이름으로 새로운 파일을 생성한다. 하지만 명시적으로 이 파일은 lodash의 타입 선언을 해주는 역할을 할 것이므로 lodash.d.ts 라고 지어준다.
보통 이런 식으로 파일 이름을 짓는 방식을 dts 파일이라고 얘기한다. 그래서 파일 이름인 lodash와 확장자인 ts 사이에 d가 들어간다는 것을 기억해 두자.
이 dts 파일을 가지고 현재 Error가 발행하고 있는 lodash 패키지의 타입을 명시해줄 것이다. dts 파일의 작성 방법은, 우선 declare 키워드, module 키워드, 패키지 이름을 띄어쓰기로 구분해서 추가하고 이어서 타입을 지정을 넣어줄 중괄호에 작성한다.
의미적으로는 import 키워드를 통해서 별도의 경로 작성 없이 lodash 라는 이름의 패키지를 node_modules라는 폴더에서 가지고 온다. 이 lodash라는 패키지는 하나의 모듈인데 그 lodash 라는 이름의 모듈을 사용할 때 타입을 선언하겠다고 해서 declare 키워드를 붙여준다. 이어서 따라오는 module ‘lodash’는 declare를 통해서 타입을 선언할 것인데 그렇게 선언하려고 하는 타입의 모듈은 lodash라는 의미이다. 그래서 declare module ‘lodash’라고 작성하고 중괄호 안으로 들어가서 lodash 패키지에서 우리가 사용하고 있는 타입을 명시해주면 된다.
// lodash.d.ts declare module 'lodash' { interface Lodash { camelCase: (str: string) => string snakeCase: (str: string) => string } const _: Lodash export default _ }
중괄호 안의 내용은 lodash 패키지에서 활용하고 있는 타입을 인터페이스로 만들어주고, lodash를 언더바(_) 기호의 변수에 할당하고 사용하고 있으니, 언더바 변수는 타입이 앞서 만들어둔 인터페이스 lodash라고 명시해준다. 그리고 기본 내보내기(export default)로 언더바 변수 내용을 반환한다.
lodash라는 패키지의 내용을 사용할 때마다 사용되는 내용의 타입을 dts 파일을 통해서 따로 결정을 해줘야지만 정상적으로 내용이 동작할 수 있다.
JavaScript로 만들어진 어떤 내용을 타입스크립트 파일 안에서 가져와 사용하려면, JavaScript 파일에서는 당연히 타입 정보를 입력하지 않기 때문에 타입스크립트가 이해할 수 있는 타입이 존재해야 지만 Error가 발생하지 않는다.
dts 파일의 이름을 원하는 대로 자유롭게 사용할 수 있지만, 특정 모듈의 이름이 아닌 예를 들어 main.ts이라는 이름으로 만들면 main.ts의 lodash 모듈 import 키워드 라인에서 Error가 발생한다. Error 가 발생하는 이유는, 패키지의 이름이 lodash인 경우 lodash와 관련된 dts 파일을 찾게 되는데 해당 모듈과 동일한 이름으로 시작하는 dts 파일이 없기 때문에 자동으로 연결되지 않는다.
dts 파일은 가져오는 모듈의 이름으로 짓지 않은 경우에는 연결해주는 코드를 작성해줘야 한다.
dts 파일의 연결
dts 파일을 연결해주는 내용은, 모듈을 가져오는 import 키워드 위쪽 라인에 슬래시(/) 기호를 3개 쓰고 reference라는 빈 태그를 추가해준다. 그리고 path 속성에 연결하고자 하는 dts 파일의 경로를 명시해주면 된다.
슬래시 기호 3개를 사용하는 것을 삼중 슬래시 지시자(Triple-slash directive)라고 하고, reference 이름의 태그로 만드는 부분을 참조 태그(Reference tag)라고 부른다.
타입스크립트에 삼중 슬래시 지시자를 통해서 reference라는 이름의 참조 태그를 사용하여 패키지에서 사용하는 내용의 타입이 명시된 파일의 경로에 잘 연결을 해주면 된다.
슬래스 두 번부터는 JavaScript 입장에서는 주석이기 때문에 JavaScript 코드로 변환했을 때도 전혀 문제가 없다. 타입스크립트 입장에서는 해당하는 파일을 어디에서 참조로 가지고 와야 되는지도 확인할 수 있는 내용이 된다.
첫 번째 방법은 dts 파일을 만들 때 피키지의 이름과 일치하도록 파일의 이름을 지정해 주었고, 두 번째의 경우는 만약 파일의 이름이 일치하지 않을 때 상중 슬래스 지시자의 참조 태그를 통해서 경로를 따로 명시해 줄 수 있는 방법이었다.
선언 파일의 이름을 만들 때 중간에 알파벳 소문자 d가 들어가도록 만들었다. 그래서 dts 파일이라고 부르는데, 여기서 d는 선언하다(declare)라는 동사의 약어이면서 또는 선언의 명사(declaration)의 약어로 d를 사용하는 것이다. 그래서 dts 파일은 타입스크립트의 선언이 들어있는 파일이며, 구현과 관련된 로직이 들어있는 것이 아닌 타입에 대한 내용만 들어 있다.
만약 main.ts 파일에서 import 키워드의 모듈을 가져오는 코드 라인에서 중괄호를 사용하는 이름을 가지고 온다면, 그런 구조에서는 당연하게 export default가 아닌 이름을 가지는 내보내기로 dts 파일의 내용을 수정해주어야 한다.
구현된 타인 선언 파일 사용하기
우리가 사용하는 JavaScript의 패키지를 이렇게 타입스크립트에서 사용할 때마다 타입 선언을 일일이 다 해줄 수는 없다. 위에서 JavaScript 패키지의 타입 선언 방법을 직접 작성해보았지만, lodash 패키지의 타입 선언이 따로 존재한다.
구글에 Definitely typed 라고 검색을 해서 아래 GitHub 페이지에 접속 할 수 있다.
https://github.com/DefinitelyTyped/DefinitelyTyped
이곳에 전세계 개발자들이 우리가 사용할 수 있는 많은 JavaScript 기능들의 타입을 직접 선언해서 기여를 하고 있다. 물론 요즘에 만들어지는 JavaScript 기능들은 애초에 타입스크립트로 만들어서 변환을 시켜 놓거나 혹은 이미 타입 선언을 내장하고 있는 경우가 대부분이다. 타입스크립트가 유행하기 전에 만들어진 JavaScript 기능도 엄청나게 많기 때문에 이렇게 difinitely typed를 활용할 수 있다.
npm install을 통해서 개발의 의존성 패키지로 설치할 수 있다.
npm install --save-dev @types/[패키지 이름]
위 명령어의 대괄호 안의 패키지 이름을 넣고 실행했을 때, 그 타입 선언의 패키지가 존재한다면 해당하는 내용이 설치가 된다. 그러면 프로젝트 내부에서 그 해당하는 타입 선언을 읽어와서 쓸 수 있다.
npm info 명령어를 통해 우선 내가 사용하고자 하는 패키지의 이름을 검색해본다. 패키지의 설치가 아닌, 패키지가 npm 레지스터에 존재하는 지 확인을 할 수 있다.
npm info @types/lodash
이제 직접 작서했던 dts 파일을 가리키는 삼중 슬래시 지시자를 주석으로 변경하고, npm install 명령어를 통해 설치를 해보자.
npm i @types/lodash -D
설치가 완료되고, main.ts 내용을 보면 rodash 부분에서 에러가 바로 사라진다. rodash 패키지의 definitely typed를 설치해서 직접 작성했던 dts 파일 처럼 전세계의 개발자들이 기여해서 만들어 놓은 타입을 가져와서 편리하게 사용할 수 있다.
definitely typed을 통해서 설치할 수 있는 패키지의 타입이 굉장히 많다. 우리가 사용할 수 있는 조금이라도 유명한 JavaScript 패키지들은 전부 다 definitely typed가 있거나 혹은 패키지 자체의 타입 선언이 이미 되어져 있는 것이다. 그래서 요즘에는 개인이 dts 파일을 직접 만들어서 관리하는 경우는 많지 않기 때문에 패키지의 타입 선언을 너무 어렵게 생각할 필요는 없다.
타입스크립트가 패키지의 타입 선언을 자동으로 인식하는 방법
설치한 types의 lodash 패키지를 어떻게 타입스크립트에서 자동으로 인식하는지 확인해보자.
definitely typed가 설치된 위치는 다음과 같다.
node_modules 폴더 > @types 폴더 > 설치한 패키지
이렇게 에이싸인(@, 골뱅이 기호)로 시작하는 types라는 폴더가 node_modules 안에 들어 있음을 기억해두자.
이제 프로젝트의 tsconfig.json 파일의 compilerOptions 안에 typeRoots라는 이름의 배열 데이터 옵션을 추가하고, 기본 값으로 node_modules 안에 들어있는 @types라는 폴더를 찾도록 명시한다. 이제 @types 폴더에 definitely types를 잘 설치해주면 타입스크립트가 자동으로 읽을 수 있다. (default)
{ "compilerOptions": { "target": "ES2015", "module": "ESNext", "moduleResolution": "Node", "esModuleInterop": true, "lib": ["ESNext", "DOM"], "strict": true, "typeRoots": [ "./node_modules/@types" ] }, "include": [ "src/**/*.ts" ], "exclude": [ "node_modules" ] }
사실 이 부분의 내용은 기본 값이기 때문에 따로 tsconfig.json 파일에 추가로 작성하지 않아도 된다.
Reference
김영웅 강사님 블로그 中 TS 파트
https://heropy.blog/2020/01/27/typescript/
김영웅 강사님 유튜브 채널
https://www.youtube.com/channel/UCcjhMpoaNvyy0StN9KgtF6w
'Front-end 개발' 카테고리의 다른 글
[패캠] 타입스크립트 문법 - tsconfig.json 구성 옵션 (20/20, 끝) (2) 2024.02.01 [패캠] 타입스크립트 문법 - 타입 가져오기와 내보내기 (export, import) (19/20) (0) 2024.02.01 [패캠] 타입스크립트 문법 - 제네릭 인터페이스와 제약 조건 (generic) (17/20) (0) 2024.02.01 [패캠] 타입스크립트 문법 - 제네릭 클래스 (generic) (16/20) (0) 2024.02.01 [패캠] 패스트캠퍼스 문법 - 제네릭 함수 (generic) (15/20) (0) 2024.02.01