한창 프로젝트를 JavaScript 기반에서 TypeScript 기반으로 변경하던 중, 타입 선언 관련 문제가 발생했습니다.

이 문제를 해결하기 위해서 다양하게 찾아보던 중 .d.ts 파일의 존재를 알게 되었습니다.

딱 봤을 때 이 친구가 해결의 실마리겠구나 느꼈죠.

 

 

하지만 정말 허무하게도 vscode를 껐다 키는 과정(...)을 통해 문제를 해결했습니다 ㅋㅋㅋㅋㅋㅋ

이 문제를 해결하기 위해서 .d.ts파일을 하루종일 검색하고, node_modules 폴더의 @types폴더의 내부도 접근해보고, stackoverflow도 한참을 뒤져보기도 했는데 말이죠...

 

그래서 그냥 이대로 넘어가면 검색하면서 이해한 내용을 까먹기도 할 것이고, 제가 이해한 내용이 누군가에게 도움이 되었으면 좋겠다는 마음이 생겨서!! 이번 포스팅에서는 .d.ts에 대해서 공부했던 내용들을 정리해볼 생각입니다.

 

목차


    0. .d.ts는 어디다 쓰는거지?

    .d.ts파일type을 정의(declare)하기 위해서 존재하는 파일입니다.

     

    그렇다면 왜 .ts파일에 타입을 정의하지 않고 따로 .d.ts를 만들어서 사용하는걸까요?

    조금 더 세부적인 용도로 생각해보면, .d.ts파일은 기존 JavaScript로 만들어진 서드파티 모듈들을 TypeScript 환경에서도 사용할 수 있도록 따로 타입만 정리해서 넣어둔 파일이라고 생각하시면 됩니다!

    해당 파일이 없다면 JS 기반의 라이브러리들은 TS환경에서 타입이 지정되지 않았기 때문에 타입체킹이 제대로 되지 않아서 정상적으로 인식되지 못하는 문제가 발생하게 됩니다.

     

    특정 라이브러리가 TS환경에서만 작동한다면 .ts 파일 내에서 타입이나 인터페이스를 선언하면 되겠지만, JS환경에서 사용되는 경우가 있을 수 있기 때문에 이렇게 별도의 파일을 만들어서 타입을 선언하게 된다고 이해했습니다.

     

    보통 프로젝트에서는 별도의 JS환경을 생각하지 않으므로 .ts파일 내부에 타입을 선언하고, 라이브러리는 JS환경을 생각하여 .d.ts파일에서 타입을 관리한다고 합니다! (일반적으로 그렇다는 것이지 반드시 그렇게 해야만 하는 것은 아닙니다!)

     

    우리가 흔히 npm으로 다운로드 받는 @types/ 가 붙은 모듈들이 바로 타입 선언만 포함된 모듈입니다!

    (궁금하시면 직접 node_modules의 @types 폴더에 들어가셔서 확인해보셔도 좋습니다!!)

     

     

    기존에는 JS방식으로 돌아가던 라이브러리를 TS환경에서 사용하게 되는 경우 타입체킹에 필요한 타입들을 불러와야 하기 때문에 이런 추가적인 타입 선언 모듈을 받아서 동작시키는 것이죠!

     

    만약 기존에 정의되어있는 타입들이 아닌 커스텀타입을 사용하고 싶거나, 정말 일부만 사용하고 싶다면 직접 프로젝트 내에 .d.ts파일을 만들어서 사용하는 수밖에 없겠죠?!

     

    그 경우 프로젝트 내부에 @type 폴더를 만들고 그 안에 필요에 따라 모듈명 폴더를 추가로 만들고 그 아래에 index.d.ts를 만들어서 타입을 선언할 수 있습니다.

    (이 과정을 마치고 나면 우리가 만든 커스텀 타입을 인식시키기 위해서 tsconfigcompilerOptionstypeRoots 속성을 추가해줘야겠죠!!! 관련 내용 역시 공식문서에 잘 나와있으니 참고하세요 ㅎㅎㅎ)

     

     

    TSConfig Reference - Docs on every TSConfig option

    From allowJs to useDefineForClassFields the TSConfig reference includes information about all of the active compiler flags setting up a TypeScript project.

    www.typescriptlang.org

     

    추가로, tsconfig에서 declaration 옵션true로 준다면 TS파일을 JS로 컴파일하는 과정에서 JS파일과 함께 d.ts 파일이 생성됩니다.

     


    1. .d.ts 파일의 내부

    .d.ts 파일에는 타입의 선언만 되어있어야 합니다.

    이렇게 구현이 없는 선언을 ambient라고 하는데, 이런 선언들이 바로 .d.ts파일에 들어가는 것이죠.

     

    그리고 declare이라는 키워드가 등장하게 되는데, 이 키워드를 사용하게 되면 컴파일러에게 해당 변수나 함수의 존재 여부를 알릴 수 있고, 또한 해당 내용들은 JS코드로 컴파일되지 않고 TS 컴파일러에게 타입 정보를 알릴 수 있습니다

     

    실제로 React에서 사용하는 타입들을 담아놓은 node_modules/@types/react의 index.d.ts파일을 살펴보겠습니다.

     

     

    어질어질할 수 있는데, 중간중간 이해하기 어려운 부분은 아래에 짧게 설명해 두었으니 참고해보시면 좋을 것 같아요!

     

    namespace는 Java로 치면 일종의 패키지 개념입니다. (TypeScript 1.5버전 이전에는 Internal modules로 불렸습니다!)

    클래스나 인터페이스, 함수와 같은 내용들을 한 파일에서 그룹화해서 관리할 수 있게 해 주는 요소입니다.

     

    export = React라고 되어있는 부분은 CommonJS와 AMD에서 일반적으로 사용하는 import / export형태를 지원하기 위함입니다.

    아래 공식 문서를 참고하시면 이해에 도움이 되실 수 있을 것 같아 가져왔습니다!

     

    Documentation - Modules

    How modules work in TypeScript

    www.typescriptlang.org

     

    export as namespace라는 문법도 등장하는데, 이 문법은 export 되는 데이터들을 하나의 네임스페이스로 묶어서 export시켜주는 문법입니다.

    이렇게 export가 된다면 import 형태로, 혹은 일반 전역변수 형태로 참조할 수 있게 되는 것이죠!

    이 부분에 대한 내용도 공식문서를 확인하시면 좋을 것 같아요!

     

    Documentation - Modules

    How modules work in TypeScript

    www.typescriptlang.org

     

     

    사실 이렇게 .d.ts 파일을 뜯어보면서 가장 중요한 부분은, declare를 이용해서 React namespace 안에 타입들을 선언하고, 이것들을 가져다 쓴다는 방식으로 동작한다는 것을 이해하는 것입니다.

     

    React에서 props를 전달할 때 많이 쓰는 React.FC 역시 index.d.ts파일 내부에 인터페이스가 잘 정의되어 있는 모습을 확인할 수 있습니다.

     

     

    이런 방식으로 타입들을 잘 모아서 가져다 사용할 수 있게 도와주는 요소가 바로 d.ts 파일인 것이죠!

     


    2. 참고자료

     

    Documentation - Modules

    How modules work in TypeScript

    www.typescriptlang.org

     

    Documentation - Namespaces

    How TypeScript namespaces work

    www.typescriptlang.org

     

    TSConfig Reference - Docs on every TSConfig option

    From allowJs to useDefineForClassFields the TSConfig reference includes information about all of the active compiler flags setting up a TypeScript project.

    www.typescriptlang.org

     

    what is the purpose of "export as namespace foo"?

    I'm using some *.d.ts files and I see in many of them the following two lines: //foo.d.ts export = foo; export as namespace foo; declare var foo; [...] I can understand that in the former one (...

    stackoverflow.com

     

    d.ts 만들기

    Node 프로젝트에서 사용하는 외부 모듈의 타입 정보를 d.ts 파일에 작성하는 방법을 소개합니다.

    www.slideshare.net

     

    반응형
    • 네이버 블로그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기