Introduction
Let’s suppose you have a large TypeScript project with a lot of features. In this project, you are tasked of refactoring one of the most important component in your entire application: the user registration form (assuming you are using React), which is an extremely detailed and vitally important feature in your application.
Alright, you have done it, you refactored everything and… now there are a lot of TypeScript errors because the types of the props that this component receives are different from all of the usages of this component in your app. How do you find all your usages easily?
Sure you can use the good old Cmd+Shift+F
or Ctrl+Shift+F
, but there’s another easier and better way to do this.
To fix this, we can use tsc
. The good thing about tsc
is that you can use it to maintain the integrity of your project and keep it free from errors.
First of all, what is tsc
?
Assuming you are new to TypeScript, tsc
is The TypeScript Compiler. It is a tool responsible for turning your TypeScript (which is a superset of JS) code into plain JavaScript. Since, as of today, browsers only understand JavaScript code, tsc
makes your TS code readable by browsers.
Alright, how do we use it?
Assuming you already have a TypeScript project with a tsconfig.json
file and also a package.json
file, add a scripts
property if there isn’t one yet.
...
"scripts": {
...
},
...
Enter fullscreen mode
Exit fullscreen mode
It’ll be here where we will add our typecheck
command:
...
"scripts": {
"typecheck": "tsc --project tsconfig.json --noEmit",
},
...
Enter fullscreen mode
Exit fullscreen mode
Alright, now let’s go over this command:
- First, we execute the
tsc
compiler - We pass the —project flag to explicitly tell the compiler that we want to typecheck the entire project using our specified config file, which is the tsconfig.json.
- Lastly, we pass the —noEmit flag to say that we do not want to output the compiled JS files into our project. If we don’t set this flag and, for example, we have a TS file located at
src/utils/boolToText.ts
, there would be created a file calledsrc/utils/boolToText.js
, which is the JavaScript version of thesrc/utils/boolToText.ts
file outputed by the compiler.
If there are no TS errors in your code, you should see something like this:
If some error(s) was found, you should see something like this:
Now you can open the files with errors and fix them
Additional configuration you can use
There are also some additional configuration I like to do to make sure my project is safe and sound, free from any errors.
Run on pre-commit with husky and lint-staged
One thing I like to do is to configure my typecheck command with lint-staged and husky on pre-commit along with my tests
and eslint
verification.
So, my .lintstagedrc.json
file looks something like this:
{
"*.{ts,tsx}": [
"eslint 'src/**' --fix",
"npm run test:staged"
]
}
Enter fullscreen mode
Exit fullscreen mode
And my .husky/pre-commit
file looks like this:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install lint-staged
npm run typecheck
Enter fullscreen mode
Exit fullscreen mode
This way, every time I commit something, it will do lint check, run my tests and typecheck my entire project.
💡 Notice: The reason why I’m not executing my npm run typecheck
inside lint-staged is that, since lint-staged only runs staged files and passes the current file being checked by argument to the command being executed, we can’t have a reference to the tsconfig.json
file (with the —project flag) and a source file to check in the same command. If you do, you’ll get a TS5042: Option 'project' cannot be mixed with source files on a command line.
error. Passing npm run typecheck
in the husky pre-commit hook separated from lint-staged will typecheck the entire project, and not just the staged files. It’s not perfect, but it works! There’s an issue in the official TypeScript repository about this, in case you want to take a look.
If you don’t have lint-staged and husky installed yet, you can refer to their official documentation:
- lint-staged
- husky
Create a task on VSCode to watch for errors
Another nice thing you can do is create a VSCode task to watch for errors in your project as you code.
To do this:
- Open the command palette
(Cmd+Shift+P)
or(Ctrl+Shift+P)
. - Select
Tasks: Configure Task
. - Select
tsc: watch - tsconfig.json
- Make sure the
"noEmit": true
option is set in the «compilerOptions» section in your tsconfig.json so thattsc
do not outputjs
files all over your project.
Now, there will be created a .vscode/tasks.json
in your project with the following content:
{
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": "build",
"label": "tsc: watch - tsconfig.json"
}
]
}
Enter fullscreen mode
Exit fullscreen mode
- Set a custom label if your want to.
{
...
"tasks": [
{
...
"label": "Watch for TypeScript errors"
}
]
}
Enter fullscreen mode
Exit fullscreen mode
- Now, you can open your command palette again and select
Tasks: Run Task
- Select your
Watch for TypeScript errors
(or the name you chose) task.
This will open a new terminal window with the execution of your task and it will keep watching for errors.
Congratulations. You are done creating your VSCode task
Conclusion
Congratulations! Now you have a error-proof project, especially if you configured husky and lint-staged too.
As always, improvements and/or corrections are welcome 😀.
Have fun coding!
Further reading
- https://spin.atomicobject.com/2019/11/20/type-checking-typescript-visual-studio-code/
- https://www.typescriptlang.org/docs/handbook/compiler-options.html
I am receiving the following error across all typescript projects that I am trying run.
TS5042 Build: Option 'project' cannot be mixed with source files on a command line.
I have downloaded a free Typescript Angular2 template, ran it and this error immediately pops up.
Has it got something to do with my global typescript installation?
7 Answers
The tsc
command can be run in two ways:
- With a
project
parameter, which points to the directory that contains atsconfig.json
. For example:tsc --project ./app
. The location of thetsconfig.json
determines the set of files that should be included in the compilation. See here for more about thetsconfig.json
: http://www.typescriptlang.org/docs/handbook/tsconfig-json.html - With a list of files as the default parameter. For example:
tsc MyFile1.ts MyFile2.ts MyFile3.ts
.
These two options are incompatible with each other because they both attempt to define which files should be compiled.
What is the command you are using to compile your project? Or are you using an IDE that runs the build for you?
Here’s the reference for the tsc
compiler options.
i was getting same error but when removed every space in my folders name as shown in path from tsc compiler it now successfully builds.See also this GitHub issue.
I have found a fix that works for me. I have more than one version of Visualstudio at c:Program Files (x86)MSBuildMicrosoftVisualStudio
Open v15.0 and copy the Typescript folder to the v14.0 folder.
The solution for me was pretty simple. I looked at the filepath for my project and realized one of the folder names in the file path had a space in it. When I renamed the folder without the space, TSC -p worked just fine. It seems like TSC, when parsing out command line args, splits it at spaces so it saw the part of my filepath name after the space as a file to compile.
You have to add "terminal.integrated.shell.windows": "C:\WINDOWS\System32\cmd.exe"
to the visual studio code user settings.
If could be of help I have a little update. As explained in the previous issues, after I’ve seen the problems with 1.8 I tried to uninstall it and reinstall 1.7 to continue to work to my projects, but even the installation was ok I had different problems compiling these asp.net 5 apps. I tried repairing vs, uninstalling and reinstalling 1.7 and 1.8 in any order without any changes.
In the end I checked the directory C:Program Files (x86)MSBuildMicrosoftVisualStudiov14.0TypeScript and I found that at the end of the uninstall of every version of typescript I have this
search for this folder and delete
At this point I tried to remove this directory completely and retried to uninstall typescript 1.7.6. and now it works fine.
I tried doing this cleaning up and installing 1.8 beta, but I continue to have the same problem, but at least now I can work on asp.net 5 projects.
I think that the problem rolling back to previous version was unable to overwrite at least the TypeScript.Tasks.dll generating an inconsistent behavior.
Could be possibile that to make work nightly builds of 1.8
and the error TS5042 solve. I hope this help you.
Not use Powershell. Use the old command.com in your configuration.
{
"files.autoSave": "afterDelay",
"terminal.integrated.shell.windows": "C:\WINDOWS\System32\cmd.exe"
}
Getting this running tsc-watch -p tsconfig.server.json --onSuccess 'npm run start'
or tsc-watch --onSuccess 'npm run start' -p tsconfig.server.json
using node v12.14.0
npm v7.12.1
on Microsoft Windows 10 Home 10.0.19042 N/A Build 19042
Same commands works just fine from WSL1 os: Debian, kernel: x86_64 Linux 4.4.0-19041-Microsoft
Example to reproduce
empl-118.zip
A-case (not my case, but new bug-like behaviour i got during research)
> npm run a
12:19:32 AM - Starting compilation in watch mode...
error TS6231: Could not resolve the path 'helloa'' with the extensions: '.ts', '.tsx', '.d.ts'.
The file is in the program because:
Root file specified for compilation
B-case with the problem from title
> npm run b
error TS5042: Option 'project' cannot be mixed with source files on a command line.
C-case same as A
> npm run c
12:21:11 AM - Starting compilation in watch mode...
error TS6231: Could not resolve the path 'helloc'' with the extensions: '.ts', '.tsx', '.d.ts'.
The file is in the program because:
Root file specified for compilation
D-case Works just fine
> npm run d
12:22:47 AM - Starting compilation in watch mode...
12:22:47 AM - Found 0 errors. Watching for file changes.
extractArgs do not respect arguments properly as I can see
Similarly for B and C cases
Windows:
> node ../tsc-watch/index.js code.ts --onSuccess 'echo helloa'
commandValue 'echo args [ 'code.ts', '--onSuccess', "'echo", "helloa'", '--watch' ]
args spliced [ 'code.ts', "helloa'", '--watch' ]
‘echo helloa’ recognized as two arguments
WSL1 Debian
> node ../tsc-watch/index.js code.ts --onSuccess 'echo helloa'
commandValue echo helloa args [ 'code.ts', '--onSuccess', 'echo helloa', '--watch' ]
args spliced [ 'code.ts', '--watch' ]
‘echo helloa’ recognized as a single argument
This comment explain why it works as it works. It is possible to add merge step for single quoted arguments, but should we?
I’m not sure, but isn’t this a typescript issue and not tsc-watch?
I’m not sure, but isn’t this a typescript issue and not tsc-watch?
Judging by comment mentioned before, actually this is neither tsc-watch or typescript problem. Just misunderstanding point with windows shell rules