DefinitelyTyped에서 제공하는 @types 패키지를 설치·선택하고 자체 타입 내장 여부와 types·typeRoots 설정을 구분합니다.
타입스크립트로 자바스크립트 라이브러리를 개발하거나,
기존 라이브러리를 타입스크립트 프로젝트에서 사용할 때
핵심은 타입 정의 파일(.d.ts)입니다.
문제는 라이브러리 수가 너무 많아
모든 .d.ts를 개발자가 직접 작성하는 것이
비효율적이고 사실상 불가능에 가깝다는 점입니다.
이러한 문제를 해결하기 위해 등장한 것이 바로 DefinitelyTyped 프로젝트와 npm의 @types 스코프 패키지입니다.
DefinitelyTyped와 @types 배포 흐름
타입스크립트로 자바스크립트 라이브러리를 개발하거나, 기존 라이브러리를 타입스크립트 프로젝트에서 사용할 때 핵심은 타입 정의 파일(.d.ts)입니다. 문제는 라이브러리 수가 너무 많아 모든 .d.ts를 개발자가 직접 작성하는 것이 비효율적이고 사실상 불가능에 가깝다는 점입니다.
1
DefinitelyTyped 프로젝트 개념
DefinitelyTyped는 수많은 자바스크립트 라이브러리에 대한 고품질의 타입 정의 파일을 제공하는 오픈 소스 프로젝트입니다. 타입 정의 파일(.d.ts)
2
@types 스코프 패키지
DefinitelyTyped에 기여된 모든 타입 정의 파일은 자동으로 npm의 @types 스코프로 패키징되어 배포됩니다. DefinitelyTyped
3
@types 패키지의 장점
자동 완성 및 타입 검사: IDE에서 라이브러리 사용 시 정확한 자동 완성( .)과 함수 시그니처 힌트를 제공하여 개발 생산성을 크게 높입니다. @types 스코프 패키지
4
DefinitelyTyped와 @types 배포 흐름 기준
정확성 타입스크립트로 자바스크립트 라이브러리를 개발하거나 기존 라이브러리를 가져올 때는 타입 정의 제공 여부와 유지 상태를 먼저 확인합니다. 비용 DefinitelyTyped는 외부 라이브러리 타입 정의를 모아 관리합니다. 확장성 @types 패키지는 런타임 코드를 포함하지 않고 npm 스코프 안에서 선언 파일만 배포해 기존 JS 라이브러리에 타입 경계를 붙입니다. 예외 설치된 타입 정의가 실제 런타임 API와 맞는지 확인합니다.
5
정확성 타입스크립트
자바스크립트 라이브러리를 개발하거나 기존 라이브러리를 가져올 때는 타입 정의 제공 여부와 유지 상태를 먼저 확인합니다.
6
비용 DefinitelyTyped
외부 라이브러리 타입 정의를 모아 관리합니다.
7
확장성 @types 패키지
런타임 코드를 포함하지 않고 npm 스코프 안에서 선언 파일만 배포해 기존 JS 라이브러리에 타입 경계를 붙입니다.
DefinitelyTyped에 기여된 모든 타입 정의 파일은 자동으로 npm의 @types 스코프로 패키징되어 배포됩니다.
즉, lodash 라이브러리에 대한 타입 정의는 npm install @types/lodash 명령어로 설치할 수 있게 됩니다.
이 @types 패키지들은 실제 자바스크립트 코드를 포함하지 않고, 오직 해당 라이브러리의 타입 정의(.d.ts 파일)만을 포함합니다.
타입스크립트 컴파일러는 기본적으로 node_modules/@types 디렉토리를 자동으로 검색하여 필요한 타입 정의 파일을 찾습니다.
사용 예시
lodash 라이브러리를 타입스크립트 프로젝트에서 사용하려고 할 때:
lodash 라이브러리 설치
npm install lodash
lodash에 대한 타입 정의 설치
npm install --save-dev @types/lodash
--save-dev 플래그는 개발 의존성(devDependencies)으로 설치하여, 실제 프로덕션 환경에는 포함되지 않음을 나타냅니다.
타입 정의 파일은 컴파일 시에만 필요하기 때문입니다.
이제 타입스크립트 코드에서 lodash를 가져와 사용하면, 타입스크립트 컴파일러는 node_modules/@types/lodash 경로의 .d.ts 파일을 참조하여 _ 객체의 모든 메서드와 속성에 대한 정확한 타입 정보를 제공합니다.
import _ from 'lodash'; // 'lodash' 모듈을 가져옴 (CommonJS 모듈이므로 esModuleInterop: true 권장)const numbers = [1, 2, 3, 4, 5];const sum = _.sum(numbers); // sum은 number 타입으로 추론됩니다. (정확한 매개변수 힌트 제공)console.log(sum); // 15const shuffled = _.shuffle(numbers); // shuffled는 number[] 타입으로 추론됩니다.console.log(shuffled);// _.sortBy(numbers, 'invalidKey'); // Error: 'string' 형식은 'lodash.ValueIteratee<number>' 형식에 할당될 수 없습니다. // 타입 정의 덕분에 잘못된 인자 사용 시 오류를 즉시 감지합니다.
만약 특정 자바스크립트 라이브러리에 대한 @types 패키지가 존재하지 않는다면, 다음 두 가지 방법 중 하나를 선택할 수 있습니다.
직접 .d.ts 파일 작성:
해당 라이브러리의 외부 API를 파악하여 직접 앰비언트 모듈 선언(.d.ts 파일)을 작성합니다 (8장 3절 참조).
이 방법은 라이브러리의 규모가 작거나, 사용하려는 부분이 제한적일 때 유용합니다.
my-lib-declaration.d.ts
declare module 'my-custom-js-lib' { export function doSomething(param: string): number;}
app.ts
import { doSomething } from 'my-custom-js-lib';doSomething('hello');
any 타입으로 사용 (최후의 수단):
정의된 타입이 없어 타입 안정성을 포기하고 any 타입으로 라이브러리를 사용하는 방법입니다.
app.ts
import SomeUntypedLib from 'some-untyped-lib'; // 타입 정보가 없으므로 SomeUntypedLib는 any 타입const lib = new SomeUntypedLib();lib.doSomethingElse(123); // 타입 검사 없이 허용
이 방법은 타입스크립트 사용의 이점을 상실하므로 가능한 한 피해야 합니다.
아래 다이어그램은 새 라이브러리를 도입할 때 타입 정의를 찾는 우선순위와, 없을 때 선택지를 비교합니다.
라이브러리 타입은 가까운 곳부터 확인합니다
새 패키지를 설치할 때는 자체 타입, @types , 직접 선언, 임시 any 순서로 타입 안정성을 최대한 유지합니다.
1
패키지 자체 타입
package.json 의 types 가 가장 신뢰하기 쉽습니다.
2
@types 설치
DefinitelyTyped에 있으면 @types/lodash 같은 개발 의존성으로 추가합니다.
3
작은 선언 작성
필요한 함수와 값만 declare module 로 좁게 적어 타입 표면을 만듭니다.
4
임시 완화
any 는 마이그레이션 중 외부 값 경계에만 두고, 반복 호출 지점은 선언 파일이나 unknown guard로 좁힙니다.
5
TypeScript는 node_modules/@types 를 봅니다
검색 위치 기본 설정에서는 별도 지정 없이도 설치된 전역 타입 패키지를 자동으로 포함합니다.
tsconfig.json 파일의 compilerOptions에서 types와 typeRoots 옵션을 사용하여 타입 정의 파일의 검색 방식을 더 세밀하게 제어할 수 있습니다.
typeRoots: node_modules/@types와 같이 타입 정의 파일을 검색할 루트 디렉토리 목록을 지정합니다. 기본적으로 node_modules/@types가 포함되어 있으므로, 대부분의 경우 명시할 필요는 없습니다. 하지만 @types가 아닌 특정 커스텀 타입 정의 경로를 추가하고 싶을 때 사용합니다.