diff --git a/packages/typescript/README.md b/packages/typescript/README.md index 46ac40671..6080b3330 100644 --- a/packages/typescript/README.md +++ b/packages/typescript/README.md @@ -304,7 +304,7 @@ export default { output: { file: 'dist/index.mjs' }, - plugins: [typescript({ tsconfig: './tsconfig.json' })] + plugins: [typescript()] }; ``` @@ -320,7 +320,7 @@ And accompanying `tsconfig.json` file: } ``` -This setup will produce `dist/index.mjs` and `dist/dist/index.d.ts`. To correctly place the declaration file, add an `exclude` setting in `tsconfig` and modify the `declarationDir` setting in `compilerOptions` to resemble: +This setup will produce `dist/index.mjs` and `dist/src/index.d.ts`. To correctly place the declaration file, add an `exclude` setting in `tsconfig` and modify the `declarationDir` setting in `compilerOptions` to resemble: ```json { diff --git a/packages/typescript/src/index.ts b/packages/typescript/src/index.ts index 3594740f9..c9f828260 100644 --- a/packages/typescript/src/index.ts +++ b/packages/typescript/src/index.ts @@ -137,7 +137,11 @@ export default function typescript(options: RollupTypescriptOptions = {}): Plugi const output = findTypescriptOutput(ts, parsedOptions, fileName, emittedFiles, tsCache); output.declarations.forEach((id) => { const code = getEmittedFile(id, emittedFiles, tsCache); - let baseDir = outputOptions.dir; + let baseDir = + outputOptions.dir || + (parsedOptions.options.declaration + ? parsedOptions.options.declarationDir || parsedOptions.options.outDir + : null); if (!baseDir && tsconfig) { baseDir = tsconfig.substring(0, tsconfig.lastIndexOf('/')); } diff --git a/packages/typescript/test/test.js b/packages/typescript/test/test.js index 2f4305b3c..1d2cc0e7a 100644 --- a/packages/typescript/test/test.js +++ b/packages/typescript/test/test.js @@ -122,6 +122,30 @@ test.serial('ensures multiple outputs can be built', async (t) => { ]); }); +test.serial('supports emitting types also for single file output', async (t) => { + // Navigate to folder and use default local tsconfig instead of specifying tsconfig via file path + // as that would have the side effect that the tsconfig's path would be used as fallback path for + // the here unspecified outputOptions.dir, in which case the original issue wouldn't show. + process.chdir('fixtures/basic'); + + const warnings = []; + const bundle = await rollup({ + input: 'main.ts', + plugins: [typescript({ declaration: true, declarationDir: 'dist' })], + onwarn(warning) { + warnings.push(warning); + } + }); + // generate a single output bundle, in which case, declaration files were not correctly emitted + const output = await getCode(bundle, { format: 'esm', file: 'dist/main.js' }, true); + + t.deepEqual( + output.map((out) => out.fileName), + ['main.js', 'main.d.ts'] + ); + t.is(warnings.length, 0); +}); + test.serial('relative paths in tsconfig.json are resolved relative to the file', async (t) => { const bundle = await rollup({ input: 'fixtures/relative-dir/main.ts',