Type checker for JavaScript?

2.9k Views Asked by At

Does anyone know if there's a good tool for analyzing JavaScript code and detecting type errors? I know that JavaScript itself is weakly and dynamically typed, but it would be really nice if I could have a program that would verify that all my field accesses are sensible and that I don't try treating a number like a string, for example. I'm aware that there are valid use cases in JavaScript where adding or removing fields or converting between different types is valid and expected, but some errors are so blatant it seems like they could be caught before the script started running.

I've heard of JSLint, but my understanding is that it's mostly a style tool rather than a semantic analyzer. If I'm wrong about this, then just telling me so would be a valid answer to this question.

4

There are 4 best solutions below

0
On BEST ANSWER

Google closure compiler does some type checking if you follow their recommendations for annotating your functions with jsDoc comments. See http://code.google.com/closure/compiler/docs/js-for-compiler.html

0
On

It's not possible to do static-analysis with confidence using any automated tool owing to the dynamic nature of JavaScript. However, one tool that does a great job is Jetbrain's WebStorm and their other IDEs that have JavaScript support.

0
On

One another option - https://github.com/yarax/typelint

It's an ESLint plugin, that does type checking based on JSDoc annotations.

In addition it supports its own extension to use Redux state or Swagger schemas (basically any JSON schema) for type checking. So you don't need to describe complex composite types by yourself.

0
On

Below is a basic example on how to do type checking in JavaScript:

const Int = (val) => {
    if (Number.isInteger(val)) {
        return val;
    }else {
        throw new TypeError(`Argument value ${val} is not integer`);
    }
    return 0; //Unreachable: for static analysis
};

const sum = function(_, numA = Int(_[0]), numB = Int(_[1])) {
    return `Sum is ${numA + numB}`;
};

console.log(sum([1, 2])); //correct
console.log(sum([1, "2"])); //incorrect