TypeScript跨目录导入接口时如何避免生成额外编译文件及目录结构
You absolutely can use the ApiResponseData interface in your pub directory files without compiling the sys/ApiResponse.ts file into your client-side output. The issue you're seeing happens because TypeScript treats regular imports as value imports, which triggers compiling the imported module into the output directory. Here's how to fix it:
1. Switch to Type-Only Imports
TypeScript 3.8+ introduced type-only imports, which tell the compiler that you're only importing types (not runtime values). This means the import won't generate any JavaScript code, and the source file won't be compiled into your output.
Update your import in foo.ts (and other pub files) to use type:
// pub/foo.ts import type { ApiResponseData } from '../sys/ApiResponse.ts'; // Now you can use ApiResponseData for type checking without runtime side effects function handleResponse(data: ApiResponseData) { console.log(data.title); }
2. Adjust pub's tsconfig.json to Exclude sys Files
To make sure the TypeScript compiler doesn't accidentally include sys directory files in your pub output, add the sys directory to the exclude array in pub/tsconfig.json:
// pub/tsconfig.json { "compilerOptions": { "outDir": "../../res/js", // Your existing compiler options (target, module, etc.) }, "exclude": [ "../sys/**/*", // Exclude all files in sys directory "node_modules" ] }
The exclude rule prevents the compiler from processing sys files during the pub build, while still allowing TypeScript to resolve the type definitions for type checking.
3. (Optional) Better Long-Term: Extract Shared Types to a Common Directory
For cleaner project organization, consider moving shared type definitions like ApiResponseData to a separate shared directory. This avoids cross-directory imports between pub and sys, making your project structure more scalable:
/ts /pub /tsconfig.json /foo.ts /sys /tsconfig.json /index.ts /shared /ApiResponse.ts
Then import the type from the shared directory in both pub and sys files:
// pub/foo.ts import type { ApiResponseData } from '../shared/ApiResponse.ts'; // sys/index.ts import { ApiResponseData } from '../shared/ApiResponse.ts'; // Regular import is fine here since sys runs on Node.js
Just make sure to exclude the shared directory from pub's tsconfig.json if you don't want it compiled into client-side output (though type-only imports will already prevent this).
Verification
After making these changes, recompile your pub directory. Your output in /res/js should go back to the original structure:
/res /js /foo.js /bar.js ...
You won't see the /sys subdirectory or ApiResponse.js anymore, and your pub files will still have full type checking for ApiResponseData.
内容的提问来源于stack exchange,提问作者Dizzy the Void

