2022-01-20 18:09 작성
2022-01-21 10:36 수정
d.ts
에서의 명시적 Module import에 관해
Table of contents
도입
// can not find module
import example from 'assets/Tiger.png';
// tsconfig
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"app/*": ["./src/app/*"],
"config/*": ["./src/app/_config/*"],
"environment/*": ["./src/environments/*"],
"shared/*": ["./src/app/_shared/*"],
"helpers/*": ["./src/helpers/*"],
"tests/*": ["./src/tests/*"],
"assets/*": ["./assets/*"],
},
}
}
위와 같이 tsconfig.json
이 설정 되어 있다고 해도 assets 폴더의 png, jpeg 등의 resources를 import 할 때 에러가 발생할 수 있다. 이 문제를 해결하기 위해 다음의 두 가지 사례를 기술해둔다.
실패 사례
// tsconfig
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"app/*": ["./src/app/*"],
"config/*": ["./src/app/_config/*"],
"environment/*": ["./src/environments/*"],
"shared/*": ["./src/app/_shared/*"],
"helpers/*": ["./src/helpers/*"],
"tests/*": ["./src/tests/*"],
"assets/*": ["./assets/*"],
},
},
// Test 1
"include": ["assets/*"],
// Test 2
"include": ["**/*.png"],
}
TypeScript의 Include를 이용해 TypeScript가 적용되는 범위를 지정해도 제대로 적용되지 않았고 똑같은 에러 메시지가 출력 되었다.
성공 사례
// d.ts
declare module 'assets/*.png' {
const value: any;
export = value;
}
Stackoverflow - declare module에서 d.ts
에서 직접 Modul을 선언하는 방법을 제시했고 위와 같이 문구를 집어넣었다. 그 결과 TypeScript에서 찾지 못하던 Reference error가 해결 되었다.
고찰
그러나 이 부분은 정확히 말해 해결이라고 볼 수는 없을 것이다. d.ts
에서 선언된 이 부분은 assets/*.png
에 대해서 ‘내가 해당 파일들이 있음을 보장’하며, 해당 File들은 어떤 Type을 가져야 함을 기술하는 것이기 때문이다. 그렇기에 fallback을 적용하는데 있어 다음의 두 가지가 선행 되어야 한다.
-
babel.config.js
File이 있는 경우plugins
의module-resolver
, 그 안의root
와alias
부분이 실제적으로 적용되어 build 할 때에도 reference check가 확실해야만 한다. -
tsconfig.json
에서babel.config.js
와 동일한 relative path에 대한 reference check가 존재해야 한다.
위의 두 가지가 제대로 적용됐음에도 module error가 발생할 때에만 fallback을 사용할 때 기대하는 Performance가 나올 것이다. 만약 위의 두 가지가 선행되지 않으면 type check는 문제없는데 build 에러가 나게 되므로 유의한다(Bug가 확인 되지 않으므로 찾는데 시간을 허비할 수 있다는 의미).
또한, 상기의 declare module은 사용하는 Library나 기존 components의 hard한 type 지정 및 타입 에러 수정에 응용 될 수 있다. 다음은 react-navigation에서 navigate
Method type이 존재하지 않아 발생하는 Type error를 수정하는 방법이다.
아래의 방법을 통해 매번
useNavigation<StackNavigationProp<any>>()
할 수고를 덜 수 있게 된다.
Advanced 시행착오1
// 최상위 디렉토리의 parent.d.ts
// navigate type error가 발생했을 때 수정 방안
import '@react-navigation/native';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
// declare const 형태의 type이 있을 경우 import를 적용하면 declare const가 제대로 적용되지 않음.
// import 사용시 아래의 example이 적용되지 않아 Workaround로 require를 사용해봤으나 제대로 Import가 되지 않음.
// 따라서 parent folder와 child folder의 d.ts로 구분해 설정을 하는 방법을 생각해보는 것도 고려해볼 것.
// require('@react-navigation/native');
// const { useNavigation } = require('@react-navigation/native');
//const { StackNavigationProp } = require('@react-navigation/stack');
// declare const example: (hello: string) => string;
declare module '@react-navigation/native' {
export function useNavigation(): StackNavigationProp<any>;
}
Advanced 개선방안
-
Parent directory
parent.d.ts
// project components와는 관계없는 third party libraries 등 import '@react-navigation/native'; import { useNavigation } from '@react-navigation/native'; import { StackNavigationProp } from '@react-navigation/stack'; declare module '@react-navigation/native' { export function useNavigation(): StackNavigationProp<any>; }
-
Child directory
src.d.ts
// project와 관련된 global type 지정 type Measure = string; declare const example: (hello: string) => string; declare module 'assets/*.png' { const value: any; export = value; }
-
tsconfig.json
설정{ ... "include": ["**/*.d.ts"], ... }
참조
저작권
이 저작물은 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.