TypeScript Version: 3.9.0-dev.20200220 (broken in 3.8.2)
Search Terms: TS5053: Option 'noEmit' cannot be specified with option 'composite'
Code
{
"compilerOptions": {
"composite": true
}
}
Expected behavior:
Run a type-check with no errors, as in 3.7 and previous versions.
Actual behavior:
# npx tsc --noEmit
tsconfig.json:3:5 - error TS5053: Option 'noEmit' cannot be specified with option 'composite'.
3 "composite": true,
~~~~~~~~~~~
Found 1 error.
Additional comments:
We use composite
in our tsconfig.json
to ensure the output directory structure is always the same.
We also use --noEmit
in our CI pipelines to ensure type-checking before building a Docker image.
Is the --noEmit
the best way to do type-checking without the overhead of running an entire build (with output files) or this breaking change should really be reverted?
Related Issues:
composite
from tsconfig.json
and use as CLI flag when building projectIs the --noEmit the best way to do type-checking without the overhead of running an entire build (with output files) or this breaking change should really be reverted?
composite
requires declaration output to actually do incremental work - use emitDeclarationsOnly
instead of noEmit
.
Is the --noEmit the best way to do type-checking without the overhead of running an entire build (with output files) or this breaking change should really be reverted?
composite
requires declaration output to actually do incremental work - useemitDeclarationsOnly
instead ofnoEmit
.
Thanks for the quick answer! When using emitDeclarationOnly
an entire build tree is created with the .d.ts
files. We're looking for an alternative to use the composite
flag when building (we can't use as CLI flag due to #36588) while using noEmit
to do a quick type-checking without the I/O overhead.
Those declaration files are the metadata that incremental
and composite
modes use to determine which files need to be checked in subsequent builds. Without them, no work is actually incremental.
I understand that composite
needs metadata to work properly, but now there's no way to run a simple type-check within the CLI without actually building something.
composite
was released in TypeScript 3.0 and worked with noEmit
until 3.8.
I'm really not against that change, but as #36588 blocks us from removing composite
from tsconfig.json
and using it on compile-time, there's no way to run a type-check without build artifacts.
I understand that
composite
needs metadata to work properly, but now there's no way to run a simple type-check within the CLI without actually building something.
composite
was released in TypeScript 3.0 and worked withnoEmit
until 3.8.I'm really not against that change, but as #36588 blocks us from removing
composite
fromtsconfig.json
and using it on compile-time, there's no way to run a type-check without build artifacts.
I've the same problem in a mono repo. so that I can continue to work, I created a tsconfig.test.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"composite": false
}
}
to use it with --noEmit:
"lint": "tsc -p tsconfig.test.json --noEmit && eslint \"**/*.{ts,tsx}\" --quiet --fix",
So I can lint my packages at least
I have the same problem but with noEmit
and incremental
. Is there any other way to run a type-check without building anything?
Don't use incremental
? If you don't want anything built, you can't get any speedup from incremental
; the built things are what incremental
uses in place of normal inputs to save time.
@weswigham Sorry, to clarify: we have incremental
set in our tsconfig
, which until now we've used for our production builds, local environment builds and type-checks on commit. For the type-check on commit we've passed --noEmit
as a CLI argument. As far as I can tell what we have to do now is add a separate tsconfig
for type-checking as @dotupNET suggested.
So I'm wondering if there's a way to avoid having two config files.
We have a similar issue. We have a monorepo and use path references, which requires composite: true
. We used to use --noEmit
to perform type-checking on commit hook, but now it doesn't seem to be possible without actually building files.
agree, --noEmit
used to work perfectly with composite: true
and incremental: true
, pls bring it back.
It did not "work perfectly" - it didn't do what it claimed to do (intelligently reuse build outputs as inputs where possible); the usage of noEmit
completely negated what the composite
and incremental
flags were meant to achieve. You can get the same behavior (build performance-wise) by _not having them set_.
@hollg you could pass --incremental false --noEmit
rather than just --noEmit
for the CI pass, no?
The problem is that they can not be unset in command line. During development, it's good to have them, but for checking during commit, it'd be better to do something like tsc --noEmit --composite false
. But right now tsc
doesn't allow to have it in command line, so we basically need to have separate config files. See https://github.com/microsoft/TypeScript/issues/36588
composite
has other baggage that ties it to tsconfig usage (namely project references), so you need a separate config file (so you can redefine the build without using project references), but for incremental
just using --incremental false
as an override on the command line works fine, afaik?
I think allowing composite to be set to false (not true) seems like a better solution here. Looking into this.
@weswigham
@hollg you could pass --incremental false --noEmit rather than just --noEmit for the CI pass, no?
This works, thanks!
@weswigham right now its impossible to use composite projects, where one of the project is react-based. Because create-react-app
adds "noEmit": true
to tsconfig automatically (even if you set it to false, once you run app it will change it to true) it makes impossible to use react and composite projects.
Its a big issue because guess over 95% of react users use create-react-app.
Should create-react-app
be adjusted to use emitDeclarationOnly
instead? Afaik it uses noEmit
because webpack handles (non-declaration) emit; but blocking _all_ emit does make the composite
(and incremental
) flags do _nothing_ (extra or better, compared to a build without them set).
Closing this since we are now allowing passing --composite false
from the command line
you could pass --incremental false --noEmit rather than just --noEmit for the CI pass, no?
For someone who found this thread after upgrading to TypeScript 3.8 and after passing --incremental false
together with --noEmit
but gets another error TS5069: Option 'tsBuildInfoFile' cannot be specified without specifying option 'incremental' or option 'composite'.
the solution is passing --tsBuildInfoFile null
as well (yeah, null
). This ain't intuitive, so it might be helpful.
@weswigham right now its impossible to use composite projects, where one of the project is react-based. Because
create-react-app
adds"noEmit": true
to tsconfig automatically (even if you set it to false, once you run app it will change it to true) it makes impossible to use react and composite projects.Its a big issue because guess over 95% of react users use create-react-app.
Eject from create-react-app.
Most helpful comment
I understand that
composite
needs metadata to work properly, but now there's no way to run a simple type-check within the CLI without actually building something.composite
was released in TypeScript 3.0 and worked withnoEmit
until 3.8.I'm really not against that change, but as #36588 blocks us from removing
composite
fromtsconfig.json
and using it on compile-time, there's no way to run a type-check without build artifacts.