Search code examples
javascripttypescripttsconfig

Typescript - migrating JS code with strict flags


I'm starting to migrate a large JS codebase into TS.

As recommended in the Migrating from JavaScript document, I started by setting the tsconfig.json file to allowJs: true.

The migration procedure is that whenever I add a new file to the codebase, I add it in TS.

Since I want to be as strict as possible for these new TS files, I've added the different strictness options in the tsconfig.json file such as "noImplicitAny": true, "noImplicitThis": true.

Thing is, once I do so I get a ton of errors for all of my non-migrated JS files that, of course, lack typings for different arguments and therefore have an implicit any type.

What is the suggested workflow in this condition? As described above, I want to:

  • Be as strict as possible for the new TS files I create.
  • Run TS standard checks on my JS files, e.g. unreached code or unused variables.
  • Not having the same TS strictness on my JS files as it will simply mean I need to migrate all of my code to TS straightaway, which is not really feasible.

Is it somehow possible with different tsconfig.json files for JS and TS files?

What is the best practice here?

Edit:

As Matt mentioned in the comment below, I was indeed using the checkJs: true flag which is what caused the compiling errors in the JS files.

I understood that even without porting your JS files to TS, you receive "out-of-the-box" type checking even when you use .js files, but that isn't happening for me.

Without the checkJs flag, I receive Unreachable code detected and 'x' is declared but is never used warnings, but that seems to be it. For some reason, I was sure that it will also catch stuff like the following:

let num = 12;
num = "aa";

But it doesn't depict any warnings (and the intellisense doesn't "know" that num is of type number).

When reading the Migrating from JavaScript article again (the "Early Benefits" section), I can see that it indeed states that all I get is a very limited typing check support.

So last thing before I close this question - is this somehow configurable or that's it?


Solution

  • You will indeed have to use two tsconfig.json files, one with "noImplicitAny": true (and any similar options) but not "checkJs": true and the other with "checkJs": true but not "noImplicitAny": true. It should be straightforward to get your build system to run tsc once on each tsconfig.json file and show all the errors. You'll probably want to set "noEmit": true in one of the two files. (If you need help with this, let me know.)

    If you are using Visual Studio Code as your IDE, then based on my brief tests, there doesn't seem to be a way to get Visual Studio Code's TypeScript language service (used for error reporting as you edit) to apply different tsconfig.json files to your TypeScript and JavaScript source files (unless you can separate the files into two folders with dependencies going in only one direction, which doesn't appear to be your scenario). So you'll have to pick one of the two configurations as your main configuration and refer to the build output for the errors detected only by the other configuration. (I can't speak for other IDEs.)