Type Checking in VS Code Without TypeScript
But how, you ask
Preface
When starting a new team project, the mention of TypeScript can be intimidating, especially to those who are new to the concept of typed languages.
I’d be lying if I said I didn’t get it. It’s a development dependency that infects your entire text editor — it underlines seemingly random function calls and variables in red; fills VS Code hints with cryptic sounding warnings, and interfaces, unions, and enums? Oh my!
It’s a big commitment to push onto a team that has little-to-no TypeScript experience, but lucky for us there’s a way to include some of the value TypeScript delivers without installing any development dependencies — or forcing an entire team to commit to a scary superset of JavaScript.
But How?
TypeScript language features are actually built into VS Code. Don’t believe me? Check this out:
The marriage of VS Code + JSDoc + TypeScript allows us to express types through JSDoc annotations, and enforce type checking with TypeScript inside a Vanilla JavaScript file. This is covered in VS Code’s official documentation.
Getting Started
What you’ll need for this tutorial:
- VS Code
- React (Optional as these principals can be applied to any JS.)
Awesome. Now, let’s create our first document — a card component (Card.jsx)!
Let’s import the card into App.jsx:
When you hover over <Card/>
, VS Code should automatically generate a hint containing an inferred function signature, like this:
There are two things to note:
- The editor didn’t provide any feedback indicating
<Card/>
requires props. - The property types for props are
any
.
Type Inference
There are various ways to enhance type inference.
ES6 default parameters (not to be confused with Component.defaultProps
):
Default parameters apply required properties to your function signature.
This means that when type checking is enabled, the <Card/>
component will be underlined in red to indicate props are required, and the hint will tell you exactly what is needed.
Destructured defaults:
Destructured defaults are interpreted as optional parameters. This can be verified by enabling type checking — you’ll notice that <Card/>
is not underlined.
And finally, JSDoc annotations:
The advantage of JSDoc annotations is how explicit type definitions can be.
It’s TypeScript’s backdoor into your JavaScript application via VS Code — meaning annotating with types and documenting your signatures is nearly the same as writing types and interfaces and documenting signatures in TypeScript.
Where they’re written and how is a bit different.
Type Checking
Hints and annotations are great, but to further idiot-proof our application, let’s kick it up a notch and enable the dreaded red underline.
Type checking per document
In App.jsx
, add the following to the top of the document:
// @ts-check
This enables TypeScript to provide visual feedback when it discovers an issue, like this:
In my example, <Card/>
is using JSDoc annotations. Let’s take a look at the hint:
Let’s fix this error:
Type checking workspace
// @ts-check
can be tedious. What if we wanted type checking to persist throughout the entire workspace without adding // @ts-check
to the top of each document?
Create the following directory + file:
.vscode -> settings.json
Inside of settings.json
, add the following:
{
"javascript.implicitProjectConfig.checkJs": true
}
Type checking should now occur throughout your project.
Additional Advice
When using JSDoc, common typedefs can be defined at the top of a document and re-used, like this:
Thanks for reading. I hope you found this helpful!