DEV Community

Cover image for Type checking your JavaScript with VS Code - the superpowers you didn't know you had
Chris Noring for ITNEXT

Posted on

Type checking your JavaScript with VS Code - the superpowers you didn't know you had

Follow me on Twitter, happy to take your suggestions on topics or improvements /Chris

Ok so you've decided that pure JavaScript is enough for your project, don't want to adopt TypeScript just yet or ever and you are using VS Code? - Then this is for you.

VS Code has some great stuff built-in that will help make your JavaScript a lot safer, from typing mistakes :)

One word @ts-check.

Yes?

-1- Reassigning inferred types

Seriously, imagine the following code:

var foo = 3;
foo = false;

We've all done it, assigned some value to a variable, forgot what type it was, and we reassign it with something it shouldn't be. You get away with it for a time, and then a crash in runtime. Just add @ts-check to this like so:

// @ts-check
var foo = 3;
foo = false; // indicates error

You get a red squiggly line under the second line and on hover it says:

Type `false` is not assignable to type `Number`

Oh nice, isn't this what strict does though?

Yes, but it does it before you run it, where you want your errors, at least I do :)

-2- Too many params

You are writing the following code:

function add(a, b) {
  return a + b;
}

add(1,2,3);

Yes, that's valid code, even though it does nothing with the third param.

Wouldn't you like to be told when you mess up like this, of course you would, and you are. You will get an error with @ts-check stating Expected 0-2 arguments but got 3 when the check it added:

// @ts-check
function add(a, b) {
  return a + b;
}

add(1,2,3); // complains about the `3`

Nice :)

-3- Help with object literals

Imagine you are declaring an object like this:

// @ts-check
let gameObject = {
  x: 0,
  y: 0,
  width: 100,
  height: 100,
  getArea() {
    return this.width * this.height
  }
}

gameObject.z;

At first look, with this, everything passes, but it shouldn't, on the last line the z property is accessed which doesn't exist on the object literal.

So how do we fix it?

We can add a JsDoc type, like so:

// @ts-check

/** @type {{x: number, y: number, width: number, height: number, getArea: Function }} */
let gameObject = {
  x: 0,
  y: 0,
  width: 100,
  height: 100,
  getArea() {
    return this.width * this.height
  }
}

gameObject.z;

And now you have VS code complaining about z.

Niice ! Don't tell me, there's more right?

-4- Supporting optional variables

Ok, so we have code where we sometimes send in optional params. How do we express that?

function doSomething(config) {
  if (config && config.shouldRun) {
    // run
  }
}

doSomething();
doSomething({ shouldRun: true })

We do all sorts of checks above to ensure that this method does what it's supposed to do, like checking the shouldRun property is actually set on the config object, if it's provided.

Yea, can your tool handle this?

Yes, like so:

// @ts-check

/**
 * @param {{ shouldRun: boolean }} [config] - Somebody's name.
 */
function doSomething(config) {
  if (config && config.shouldRun) {
    // run
  }
}

doSomething({ canRun: false}); // this now indicates an error
doSomething({ shouldRun: true })

Above we get an error if we get an error on our first invocation of doSomething() as it doesn't contain an object with shouldRun property.

-5- Opt out

You can opt out of checking certain things with the directives @ts-ignore or @ts-nocheck. By taking our previous example you can ignore lines that would give an error:

//@ts-ignore
doSomething({ canRun: false});

This will not give an error.

Learn more

I do like TypeScript but I recognize it's not for everybody and every project. Small checks like this can make a lot of difference for your project. I hope it was useful.

Checking JS files
This page together with VS Code is now your best friend, at least it's mine :)

Top comments (6)

Collapse
 
functional_js profile image
Functional Javascript

Good work Chris.

Tip:

a.
create a tsconfig.json file in the root of your project or monorepo, and add...

"allowJs": true /* Allow javascript files to be compiled. */,
"checkJs": true /* Report errors in .js files. */,

and you won't ever need... // @ts-check

b.
Type your data with JSDoc.
Now you have all the Typescript services, while keeping your code pure JavaScript.
The best of both worlds.

Example:
Alt Text

Collapse
 
softchris profile image
Chris Noring • Edited

hey.. thanks.. yea that exist as well.. Just wanted to give people the "try before you buy experience". But you are right a config file is better.

Collapse
 
stereoplegic profile image
Mike Bybee • Edited

don't want to adopt TypeScript just yet or ever

If this were Facebook, I'd tag the page @I Feel Personally Attacked By This Relatable Content.

But yes, even being the JS (over TS) advocate that I am, I'll gladly admit that ts-check in VS Code is awesome. I enable it both in my editor settings and project settings (for other devs)

Collapse
 
softchris profile image
Chris Noring

haha.. yea I mean I like the pragmatic approach, whatever fits the problem or team you're in :)

Collapse
 
rodmirsantana profile image
Rodrigo Miranda Santana

Nice tip, man! I feel like this is similar to "sinking your toes underwater" with TypeScript because depending on the project, you won't really need it or it could slow down the development. I find it really useful, since I dominate JS quite well, but am still a beginner with TS. Thanks!

Collapse
 
uf4no profile image
Antonio

🤯 Ok, I gotta try this NOW