질문 배경:
타입스크립트는 기존 JS 애플리케이션에 정적 타입화를 추가하기 위해 설계되었습니다. 외부 또는 순수 자바스크립트로 작성된 모듈을 연결할 때, 타입이 없을 경우 어떻게 타입화할까요? 이 경우 타입스크립트는 소위 선언 파일(.d.ts)을 사용하거나, 자동으로 타입을 추론합니다(가끔 잘못된 경우도 있습니다).
문제:
타입스크립트가 가져오기를 할 때 적절한 타입 설명을 찾지 못하면 변수는 any 타입을 가지게 되며, 이는 타입 안정성의 완전한 손실을 의미합니다. 이는 컴파일러가 감지하지 못하는 오류와 런타임의 버그로 이어질 수 있습니다. 개발자들은 종종 가져온 함수/객체에 대해 명시적으로 타입을 선언하는 것을 잊습니다.
해결책:
코드 예제:
// 1. JS 모듈 가져오기에 대한 명시적 타입화 import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. myLib.d.ts 파일이 있는 JS 모듈에서 가져오기 — export function myFunc(x: number): boolean; import { myFunc } from './myLib'; // 3. 타입이 없는 모듈을 가져오고 명시적으로 타입을 정의 import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;
주요 특징:
타입스크립트가 선언 없이 가져온 JS 모듈의 타입을 자동으로 추론할 수 있나요?
아니오, 파일이 자바스크립트로 작성되었다면, 타입 선언이 없는 경우 타입스크립트는 any로 추측해야 하며, 타입에 대한 정보는 기본적인 경우(예: export const x = 1;)를 제외하고는 손실됩니다.
JS 모듈에서 새로운 필드가 생길 경우 가져온 타입을 "확장"할 수 있나요?
오직 선언 파일(.d.ts)을 업데이트해야 가능합니다. 타입이 .d.ts에 고정되어 있다면, 타입스크립트는 이를 "진리"로 사용하고, 새로운 필드는 타입 없이 남거나 오류를 유발할 것입니다.
@types/ 및 선언이 없는 외부 JS 모듈을 타입스크립트 프로젝트에 가져오는 것이 안전한가요?
아니오, 이는 안전성을 크게 저하시킵니다 — 모든 가져오기 작업이 untyped(any)로 되어 컴파일러가 오류를 내지 않고, 모듈이 불러올 수 없거나 API가 변경된 경우에도 오류를 내지 않습니다. 이러한 모듈과 작업하는 것은 명시적 타입화 또는 코드의 격리와 같은 임시 해결책으로만 허용됩니다.
개발자가 선언이 없는 외부 JS 라이브러리를 가져와 API를 확신하며 사용하고, 타입은 any입니다. 라이브러리 업데이트 후 메서드 시그니처가 변경되지만 오류가 발생하지 않고 런타임에서 버그만 발생합니다.
장점:
단점:
선언 파일 .d.ts를 생성하거나 @types/ 패키지를 추가하여 API 설명이 본래 JS 모듈에 엄격하게 일치하는 경우입니다. 모든 가져온 메서드가 타입화되어 있으며, IDE가 자동 완성을 제안하고 모든 불일치가 컴파일 오류로 표시됩니다.
장점:
단점: