Typescript: Allow tsconfig.json when input files are specified

Created on 26 Sep 2018  路  26Comments  路  Source: microsoft/TypeScript

I don't know why the tsconfig.json is ignored even when the --project or -p option is specified.
In my opinion, the right implementation should be:

  • If no --project or -p option: Ignore tsconfig.json
  • Otherwise: Use the configuration file specified. All the options used in the command line should overwrite the ones of the configuration file. E.g. The include/exclude keys of the tsconfig.json will be ignored when input files are specified.
In Discussion Suggestion

Most helpful comment

A pretty common practice is to have a pre-commit hook to compile only the staged files in your git project (It makes no sense to compile all the project).
If you try to create this hook that runs tsc over each staged file, you won't be able to use the tsconfig.json, as you are specifying some input files. @andy-ms

All 26 comments

I don't know why the tsconfig.json is ignored even when the --project or -p option is specified.

Could you provide a repro for a situation where tsconfig is ignored?

Sure @andy-ms , but I mean, this is not even a bug. This behaviour is explicitly explained in the docs: When input files are specified on the command line, tsconfig.json files are ignored.

When you do tsc file.ts -p tsconfig.json you get:
captura de pantalla de 2018-09-26 22-34-25

The lines of code are pretty easy to find

I just can't understand why it's implemented this way.

Probably because no one's implemented it -- could you explain what the use cases are?

A pretty common practice is to have a pre-commit hook to compile only the staged files in your git project (It makes no sense to compile all the project).
If you try to create this hook that runs tsc over each staged file, you won't be able to use the tsconfig.json, as you are specifying some input files. @andy-ms

I have another use case for this. We have many projects that use typescript, and would like to reduce boilerplate and keep our typescript config in one place, so it can be uniformly applied across all our projects for consistency.

At the moment, there isn't a way to do this, since you can't specify both a glob of files to check, and an external path to a tsconfig.json file. The only workaround in the meantime is to copy/paste a tsconfig.json file into the root of every project and have it only contain an "extends" statement. This isn't the end of the world, but it's more boilerplate than we want - the fewer duplicate files across multiple projects we can have, the better.

This same goal is easily accomplished with TSLint, by using their --config option as well as a glob of files to lint. Is there any specific reason why it is disallowed by typescript itself? If not, I would be happy to take a stab at implementing it via pull request, just want to make sure its ok with maintainers.

related, but never considered #12958

I have a different use case that needs this as well. We have a pre-commit hook that does a quick type check (tsc -p tsconfig.json --noEmit). Currently it checks all the files specified in tsconfig.json, but it would be nice to only type check the files that were modified. We are currently using lint-staged to run linting tools on modified files, it would be great to only run the type check on the modified files too.

Like @brapifra said here, https://github.com/microsoft/TypeScript/issues/27379#issuecomment-424879463, it's written in the docs that this should be possible, but it clearly isn't.

ref #22649, #13575

We have some questions for everyone in this thread

Long story short, the real problem we see is that people make a tsconfig.json, then run

tsc someFile.ts

and get garbage confusing errors because e.g. their tsconfig specifies target: ESNext and the error says something like "This is an ES5+ only API, change your target!". So we'd like to change that so that tsc always picks up a nearby tsconfig file, and provide an opt-out like --ignore-tsconfig for people who want to ignore it intentionally.

However, we're not sure what tsc someFile.ts means if there's a tsconfig present:

Question 1, do we:

  • Overwrite the files setting
  • Append to the files setting
  • Prepend to the files setting (order rarely matters but sometimes does...)

Question 2:

  • Are include and exclude still in play if there are some files specified on the commandline?

Question 3:

  • What if someFile.ts was in the exclude list?

Thoughts?

Just my two cents:

A pretty common practice is to have a pre-commit hook to compile only the staged files in your git project (It makes no sense to compile all the project).

This use case seems problematic in general, since (AFAIK) TS needs to see your whole project for some things to work (e.g. const enum, declaration merging), unless you use isolatedModules which disables those features.

Question 1.

I would expect that we'll "Overwrite the files setting".

Question 3.

If we'll treat someFile.ts as file to override files list, then no problem here - from the docs:

Files included using "include" can be filtered using the "exclude" property. However, files included explicitly using the "files" property are always included regardless of "exclude".

Question 2.

IMO include should be ignored in this case.

I think there is cases when some modules pollute global scope and it might break the compilation (because not all modules require that modules with globals even if they use them), but I believe developers should import deps explicitly (via triple-slash directives or even import statements in this case).

So we'd like to change that so that tsc always picks up a nearby tsconfig file, and provide an opt-out like --ignore-tsconfig for people who want to ignore it intentionally.

@RyanCavanaugh So, we will not be able to pass path to the custom tsconfig via --project CLI option, right? I believe it's a use case as well and it would be good to cover it too.

This can be hackily worked-around with jq (YMMV: probably lots of edge cases this won't work for, *sh only, and at this point you might prefer to write a wrapper js file which uses child_process):

tsc $(cat tsconfig.json | jq -r '.compilerOptions | to_entries[] | "--\(.key) \(.value)"') path/to/dir/**/*.ts

At very least we should have a way to tell tsc to use certain tsconfig.json, so I think -P, --project argument should work either way. And I agree with @timocov, overriding files with input should put the whole thing straight.

We have some questions for everyone in this thread

@RyanCavanaugh For my case, which is to focus on sub-sections of a large code-base going through a large migration that yields many errors all over the place, I would be fine if tsc would simply use tsconfig.json as normal for its work but only _print_ errors that occur in the files I鈥檝e specified. I.e. it being simply a filter.

Perhaps it would be more explicit to have an option for that, but I don鈥檛 feel strongly about it.

$ tsc --pretty --show-errors-from=./src/Apps/WorksForYou/{**/,}*.{ts,tsx}

Hello. I too am on the same lint-staged / lint-prepush boat where I would like to have a git hook verify that a list of files pass the typecheck settings specified in tsconfig's compilerOptions.

Question 1, do we:

  • _Overwrite_ the files setting
  • _Append to_ the files setting
  • _Prepend to_ the files setting (order rarely matters but sometimes does...)

I expect usage like tsc -p ./tsconfig.json myfiles.ts, for myfiles.ts to overwrite/replace the files setting. I would just like to "steal" the 20+ compilerOptions from tsconfig.json and get myfiles.ts typechecked with these compilerOptions instead of having to re-construct them in the CLI.

Thank you.

Any update on this? As it stands using tsc on a precommit hook isn't very viable for large projects.

The documentation mentions this scenario:

Transpile any .ts files in the folder src, with the compiler settings from tsconfig.json
tsc --project tsconfig.json src/*.ts

It does not seem to work. Should documentation be updated to remove the misleading example?

I'm also in the camp that wants to run the compiler in a pre-commit hook.

Inspired by @mmkal's suggestion, I put together this simple node script: https://gist.github.com/dsernst/b1d2df3bb5be777e1dcb27e5c0d2474d#file-typecheck-js-L13

Example w/ error:

Screen Shot 2020-02-04 at 4 01 37 AM

Otherwise:

Screen Shot 2020-02-04 at 3 51 38 AM

Works great for my use-case. Hope others may find useful. :+1:

@JasonKaz, @Brapifra try to declare external lint-staged config like here. Option -p tsconfig.json can be omitted for root tsconfig.

Then reinstall husky and lint-staged to avoid mistakes.

Just wanted to throw another perspective in: a colleague new to TypeScript expected tsconfig.json to govern the transpilation of individual files as well, just as eslint reads .eslintrc when it's passed only one file to lint.

Hey, I've built https://npm.im/tsc-files which is a tiny wrapper on tsc to handle my need to type-check specific files with lint-staged. Hope it helps some of you.

I'm afraid my solution (https://npm.im/tsc-files) will miss type errors on other files. :disappointed:

For example, suppose changing foo.ts will break bar.ts. If you use lint-staged, only foo.ts will be type-checked (because it's the only staged file) and the type error that appeared at bar.ts won't be caught. If anyone knows how to fix that, please send me a PR.

There are explicit examples in https://www.typescriptlang.org/docs/handbook/compiler-options.html which show usage of --project and input files together... tsc --project tsconfig.json src/*.ts

@willstott101 Yes, it was mentioned above, but it doesn't seem to work. In fact, the new version of the documentation doesn't have that one example anymore: https://www.typescriptlang.org/v2/docs/handbook/compiler-options.html

Adding to the responses to the questions:

Question 1

  • Overwrite the files setting

Question 2

  • Ignore the include and exclude settings if files are specified on the commandline

Question 3

  • Not applicable due to answer to Question 2
Was this page helpful?
0 / 5 - 0 ratings

Related issues

weswigham picture weswigham  路  3Comments

Antony-Jones picture Antony-Jones  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

wmaurer picture wmaurer  路  3Comments

remojansen picture remojansen  路  3Comments