.d.ts 파일을 js 프로젝트에서 사용할 수 있을까요?
js 개발자의 타입 안전성을 보장하면서 말입니다.
아래 페이지의 스크립트를 이용하여 js 파일의 대략적인 타입을 .d.ts 파일로 추출한뒤, .d.ts의 타입을 좀 더 상세하게 작성했습니다.
https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html
npx -p typescript tsc src/**/*.js --declaration --allowJs --emitDeclarationOnly --outDir types
.d.ts 파일을 .js 파일과 같은 위치에 위치시킨 뒤, ts 파일에서 임포트 하면 타입 완성이 잘 됩니다.
즉 .d.ts는 ts 프로젝트를 위한 헤더 역할을 수행합니다.
하지만 .d.ts의 대상이 되는 js 파일에서는 타입 완성이 되지 않는 것을 볼 수 있었습니다.
a.js:
export function abc( x, y ) { return !!(x-y)}
a.d.ts:
export declare function abc(x: number, y: number): boolean;
b.js:
import { abc } from './a'
기대 효과 :
실제 효과 :
- a.js > (any, any) => void
- b.js > (number, number) => boolean
생각한 대로 js에서 타입 완성이 되지 않습니다.
저와 같은 생각을 한 사람이 없었을 리가 없었습니다.
TL;DR : .d.ts와 js를 매핑하는 것은 기술적으로 간단하지 않으므로, 해당 기능이 필요하면 jsDoc을 쓰세요
https://github.com/microsoft/TypeScript/issues/14342
.d.ts에서 .js 파일로의 매핑은 간단하지 않습니다.
예를 들어 Class입니다.
해당 기능은 ES6 미만에는 존재하지 않기 때문에 소스와 타입의 1대1 매핑이 어렵습니다.
즉, .d.ts 파일은 js 파일을 ts에서 컨슘하려는 사용자를 위해 존재하는 헤더 파일과 같은 역할을 합니다.
따라서 js 파일의 .d.ts 파일을 이용한 타입 체크는 간단하지 않습니다.
Workaround
하지만 위 링크에서도 언급하였듯이 전혀 방법이 없는 것은 아닙니다.
https://github.com/microsoft/TypeScript/issues/14377
아래와 같이 jsDoc과 .d.ts 기능을 섞어서 사용하면 됩니다.
지금으로서는 js 파일의 오염을 최소화 하는 가장 간단한 방법인 듯 합니다.
사람의 공수가 좀 들어가야하는 단점이 있습니다.
babel을 이용해서 어느 정도 자동화 할 수 있는지 조사해 볼 예정입니다.
/** @type {import("./a").a} */
export function abc( x, y ) { return !!(x-y)}
비슷하게 동작하는 바벨 플러그인
export default function (babel) {
return {
name: "ast-transform", // not required
visitor: {
FunctionDeclaration(path) {
path.parentPath.addComment("leading",`* @type{import("./${path.node.id.name}"}.${path.node.id.name}`);
}
}
};
}
참고
https://medium.com/homeday/confident-js-series-part-2-types-jsdocs-and-declaration-files-23ec2df6c47
https://www.detroitlabs.com/adding-custom-type-definitions-to-a-third-party-library/
https://www.staging-typescript.org/docs/handbook/declaration-files/dts-from-js.html
'FrontEnd' 카테고리의 다른 글
리액트 디자인 패턴 : 컴파운드 컴포넌트 패턴 [Compound Component Pattern] 2 (0) | 2022.09.15 |
---|---|
[Babel] 바벨 플러그인을 작성하며 AST 배우기 (0) | 2022.09.14 |
Redux Toolkit : Usage Guide(사용 가이드) (0) | 2022.09.13 |
Redux Toolkit : Immer와 함께 사용하기 (0) | 2022.09.12 |
[번역] Mobx로 배우는 반응형 프로그래밍(reactive programming)의 원리 (0) | 2022.09.12 |