Skip to content

TSC build errors not reported with output cache #42874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
brieb opened this issue Feb 19, 2021 · 12 comments
Closed

TSC build errors not reported with output cache #42874

brieb opened this issue Feb 19, 2021 · 12 comments

Comments

@brieb
Copy link

brieb commented Feb 19, 2021

Bug Report

When running tsc -b on a project with a pre-existing output directory, we were not seeing errors reported even though they are present in the editor. Removing the output directory and running tsc -b again resulted in reporting the errors as expected.

🔎 Search Terms

build, cache, tsbuild.info, errors missing

Possibly related issue: #42769

🕗 Version & Regression Information

  • Issue observed on TS 3.8.3, 3.9.3 3.9.9, 4.0.7, 4.1.3, 4.3.0-dev.20210218

💻 Code

https://github.com/brieb/ts-issue-build-cache

Repro steps:

Git checkout the repro repo and run yarn

Run ./node_modules/.bin/tsc -b frontend/proj-03/tsconfig.json

Change contents of frontend/proj-01/Component1.tsx to

import React from "react";

type Props = {
  prop1: string;
};

function Component1({ prop1 }: Props) {
  return <div>{prop1}</div>;
}

export default Component1;

(as diff)

diff --git a/frontend/proj-01/Component1.tsx b/frontend/proj-01/Component1.tsx
index 7b9c891..b91fb2f 100644
--- a/frontend/proj-01/Component1.tsx
+++ b/frontend/proj-01/Component1.tsx
@@ -1,11 +1,11 @@
 import React from "react";
 
 type Props = {
-  prop: string;
+  prop1: string;
 };
 
-function Component1({ prop }: Props) {
-  return <div>{prop}</div>;
+function Component1({ prop1 }: Props) {
+  return <div>{prop1}</div>;
 }
 
 export default Component1;

Save the file and make no other changes.

Re-run ./node_modules/.bin/tsc -b frontend/proj-03/tsconfig.json

🙁 Actual behavior

No errors are reported even though we'd expect an error to be reported for frontend/proj-03/Component3.tsx

But if we run rm -rf .tsbuild then ./node_modules/.bin/tsc -b frontend/proj-03/tsconfig.json, we do see the error as expected.

🙂 Expected behavior

We would expect the following error to be reported

frontend/proj-03/Component3.tsx:9:19 - error TS2322: Type '{ prop: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<Pick<Props, "prop1">, any, any>> & Readonly<...> & Readonly<...>'.
  Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<Pick<Props, "prop1">, any, any>> & Readonly<...> & Readonly<...>'. Did you mean 'prop1'?

9       <Component2 prop="value" />
                    ~~~~


Found 1 error.
@sheetalkamat
Copy link
Member

This seems like configuration error from tsc -b perspective. By stating that proj-03 depends only on proj-02 you are saying if .d.ts files for proj-02 dont change then do not build proj-03 which is what is happening as part of the change. You need to reference proj-01 as well.

@brieb
Copy link
Author

brieb commented Feb 19, 2021

Gave that a try in the repro repo, and it worked! Interesting, I would have expected transitive type changes to be picked up. While the d.ts files for proj-02 don't actually change, the types do because they are based on proj-01. For correctness, would this mean listing out all transitive dependencies in all of our project tsconfigs? We have automated tooling to generate the tsconfigs, so we could do that. Though they'd get to be quite long. Out of curiosity, what would it require to transitively check dependent projects when a cached output is present within TypeScript itself?

@sheetalkamat
Copy link
Member

references are not transitive and you have to list them all if you need and use those

@brieb
Copy link
Author

brieb commented Feb 19, 2021

Okay, thank you for confirming. I'll go ahead and mark this as closed.

@brieb brieb closed this as completed Feb 19, 2021
@brieb
Copy link
Author

brieb commented Feb 19, 2021

Just to report back, this resulted in a +512,457 −4,780 diff. That's a lot of additional configuration to be checking into our monorepo. So, we're evaluating whether we should generate these on-the-fly at build time, because the editor experience worked as expected even without listing out all the transitive deps. Just noting this as a data point for further consideration of transitively checking dependent projects when a cached output is present within TypeScript itself.

@RyanCavanaugh
Copy link
Member

cc @DanielRosenwasser for FYI

@DanielRosenwasser
Copy link
Member

So just catching myself up here: is the current behavior that project references have behavior that's similar to --assumeChangesOnlyAffectDirectDependencies?

That is, a change to A in A <- B <- C does not cause a re-check in C?

@brieb
Copy link
Author

brieb commented Feb 19, 2021

That is my understanding from the explanation. If the d.ts files emitted for B as a result of the change in A are the same as the previous build, then C will not re-check.

That's assuming these refs.

C:
  refs: [B]

B:
  refs: [A]

A:
  refs: []

And the suggestion was that A needs to be a ref in C for this to work properly.

C:
  refs: [A, B]

B:
  refs: [A]

A:
  refs: []

@sheetalkamat
Copy link
Member

So just catching myself up here: is the current behavior that project references have behavior that's similar to --assumeChangesOnlyAffectDirectDependencies?

Project level.. Not within the project.
tsc -b behavior is that it checks upto date stamp for the d.ts from referenced projects and if they are not changed, the projects referencing it are not built.

@DanielRosenwasser
Copy link
Member

Project level.. Not within the project.

Yeah, I was just trying to put together a good analogy. That does seems kind of surprising.

this resulted in a +512,457 −4,780 diff.

@brieb this is configuration in your tsconfigs? How many projects are you working with?

@brieb
Copy link
Author

brieb commented Feb 20, 2021

Adding transitive projects affected 877 of our tsconfig.json files. We have 992 projects, in total.

@brieb
Copy link
Author

brieb commented Feb 24, 2021

Just to report back - We got the diff down to +185,070 −49,318 by changing the formatting, which was more acceptable.

Though another issue is that we have MANDATORY_REVIEWERS files in the root of most of our project that require review from one of the teams listed in the file if something in their project folder changes. The dev experience would be poor if adding a dependency to my project resulted in updating the tsconfigs of all projects that depend on my project, potentially incurring mandatory reviews. So, we're looking into generating the tsconfigs containing the transitive dependencies automatically during the build step instead of checking them in.

This isn't ideal because the tsconfigs people are developing with locally don't match what's running in CI, and the lack of listing transitive deps could also affect other things like tsc --watch. But, this seems like our best option at the moment unless this was supported natively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants