tsconfig noEmit error: Cannot reference tsconfig if it extends other tsconfig.
ZerdoX-x opened this issue ยท 21 comments
Bug Report
๐ Search Terms
- tsconfig.json
- noEmit
- extends
- reference
- Referenced project may not disable emit.
๐ Version & Regression Information
Tried 4.8.0-beta, 4.7.3, 4.7.4, and 4.6.3
โฏ Playground Link
๐ป Code
Couldn't reproduce this in Bug Workbench, but here is my minimal reproduction repo:
https://github.com/ZerdoX-x-issue-reproducer/microsoft-TypeScript-49844
tsconfig.json:
tsconfig.test.json:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"composite": true,
"noEmit": true
}
}tsconfig.base.json:
{
"include": [
"src/**/*.d.ts",
"src/**/*.js",
"src/**/*.ts",
],
"compilerOptions": {
"noEmit": true,
}
}๐ Actual behavior
๐ Expected behavior
๐ค Other info
UPDATE: Since this issue keeps receiving comments and attention, I would like to let you know that I don't suffer from this issue anymore, but reproduction will be opened as long as my account exists :) Afair I was using SvelteKit and I just wanted to get proper type checking for all of my files: 1) source files which would or would not get bundled to be running on client and/or server 2) configuration files, where some files use ESM, some still support only CJS 3) tests.
In newer projects I achieve this goal and do not stumble upon this issue, also it got easier now since new ESLint flat config which will be released in next major release.
facing the same issue and is driving me crazy :(
facing the same issue and is driving me crazy :(
For me it doesn't affect anything. Just a visual error in vscode, so it's fair enough to place a comment with linking this issue above "references": (glad typescript.json is JSONC) and ignore it without remorse.
This configuration doesn't make any sense; every behavior of having a reference is dependent on the output files of the referenced project being present. What are you trying to achieve?
Question: is there an easy way to type-check with a single tsc run, without emit, and with different sets of files using different libs? Or do we have to use multiple tsc runs?
Question: is there an easy way to type-check with a single tsc run, without emit, and with different sets of files using different libs
No
This configuration doesn't make any sense; every behavior of having a reference is dependent on the output files of the referenced project being present. What are you trying to achieve?
Of course this configuration doesn't make any sense. Because this is not a configuration but a minimal reproduction of the issue. If you need to see my full production setup, I've added all configs to the my-full-configuration folder.
That doesn't really answer my question, I guess.
Referencing a project does the following:
- Changes imports of
.tsfiles to their corresponding.d.tsfiles (undernoEmit, those .d.ts files don't exist) - Causes
tsc -bto rebuild the upstream project if it's out of date (if it doesn't emit, this question doesn't make any sense) - Adds any declaration
outFileto the current project (undernoEmit, those .d.ts files don't exist)
If I don't reference tsconfig.test.json in tsconfig.json I will end up with errors like this while trying to import from $lib (alias is set in tsconfig.base.json which is inherited in tsconfig.test.json) in files which are excluded in tsconfig.json

And also I noticed that vscode says I don't have tsconfig loaded for this file (and that's the reason why aliases doesn't work). Is this an issue with vscode?

But when I do reference, vscode shows loaded tsconfig.test.json as expected for this file.
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
Nice.
add
"include": [],
"files":[]
in base config get rid of the error message
What are you trying to achieve?
@RyanCavanaugh, based on @ZerdoX-x's other comments, I'm assuming that the goal is to have type checking for test files without including them in the project's output. At least, that's what I need, and that's how I stumbled upon this issue.
TypeScript's Project Reference Documentation suggested to me that Project References were the way to handle monorepos in NPM, keep TS working with tests, and keep the test files out of the build directory simultaneously. (Developers shouldn't need to include a rm -rf command in their build step. The compiler should simply exclude all undesired files from the build output.) I haven't found any clear documentation on how to handle this use case.
If you aren't going to reopen the issue, would you be willing to give a reasonable alternative? Maybe there's something we're missing?
What also might be coming out is a desire for simplicity. To expound a little more, many people want the ability to say, "Type Check my entire monorepo" in one command. But that gets difficult when there are files intended to be included in the output (regular files from several scoped packages) and files not intended to be in the output (such as test files and configuration files).
Maybe clarity on what the recommendation is for monorepos would also be helpful? My goal is to avoid getting caught up in the chaos of turborepo, yarn workspaces, etc. I just want to work with simple NPM and TS for my monorepo.
In my head the ideal solution is just having an option to make tsc just hold the necessary reference declaration output in memory or in an internally handled temporary scratch/cache dir for the entirety of the command's run without any reading or writing to the file system of the monorepo. An ever increasing size of devs are only using ts for intellisense in their IDE and as a CI test step or commit hook, no compiling. Can't really find any solution to this myself ๐
Solution for us was to configure a base tsconfig.json with files as an empty array:
{
"$schema": "https://json.schemastore.org/tsconfig",
"files": [],
"references": [
{ "path": "./tsconfig.root.json" },
{ "path": "./scripts/tsconfig.json" }
]
}Then the error message Referenced project may not disable emit goes away.
Check out some examples:
- @RyanCavanaugh 's example demo repo for TypeScript Project References: https://github.com/RyanCavanaugh/project-references-demo
- Our example with the
@typescript-eslint/*packages typescript-eslint/typescript-eslint#2094 (comment)
Came here through Google, none of the suggested solutions so far helped me out. For me, I had to add "compilerOptions": { "declaration": true }.
@tylim88 @karlhorky Unfortunately, your solution seems to fall flat in a "triangular dependencies" situation, i.e. when my main tsconfig.json references two projects A and B, and B also references A (code).
@karlhorky In particular, @RyanCavanaugh's demo that you linked to does not disable emit. The tsconfigs explicitly specify outDirs for each project.
EDIT: In light of what @RyanCavanaugh wrote here, this makes sense: Project references rely on emitting declarations.ยน I have therefore updated my code example to fix the "noEmit" error by enabling emitDeclarationsOnly and setting an outDir.
ยน) If the individual projects don't actually reference each other (like they do in my code example), i.e. if only the main tsconfig.json contains references, then of course there is no issue with enabling noEmit because each project can be type-checked separately without depending on the types of any other projects.
@atollk "declaration": true is already the default for composite projects, compare https://www.typescriptlang.org/tsconfig/#declaration
@ZerdoX-x Have you found a solution for SvelteKit projects?
I don't suffer from this issue anymore, but reproduction will be opened as long as my account exists :) Afair I was using SvelteKit and I just wanted to get proper type checking for all of my files
I am attempting to differentiate tsconfig(s) for universal and server modules, but cannot enable noEmit.
afaik i created separate tsconfigs for source and config files. same for tests
Now I don't suffer from this issue. Maybe I could compare my current project configs with repro but seems like your's different.
separate tsconfigs
this was the hardest for me. how to merge some options, override extend ntc. somehow i managed to handle that tooling and also I don't use vscode now either, moved to neovim
add
"include": [], "files":[]in base config get rid of the error message
Thanks! ๐


{ "references": [{ "path": "./tsconfig.test.json" }], "compilerOptions": { "noEmit": true } }