Monday, 20 June 2011

JavaScript, Type-checking, and Preconditions

So JavaScript doesn't have type-checking. Which was the root source of a bug that took me a while to find.

I'm so much more comfortable with strong type-checking. In many languages, I can create a new type, including its allowable values. In Java, for example, here's a type I created:

public enum RelationshipType {
    ONE_TO_ONE,
    MANY_TO_MANY,
    ONE_TO_MANY,
    MANY_TO_ONE
}

Now I can specify that a function (method, actually) only accepts one of these four values wherever I need a relationship type.

In JavaScript, a function parameter can be ANYTHING - number, string, array, or object. You need to manually check the values. Which leads to template code like this:

function createRelationship(type) {
    if (!(type === 'one_to_one' ||
type === 'many_to_many' ||
type === 'one_to_many' ||
type === 'many_to_one')) {
throw 'IllegalArgumentException';
}

// now do the actual stuff for the function

}

In Java I like to use the Preconditions class from Google's guava-libraries. I wondered if I could do something similar in JavaScript to avoid this template code for simulated type-checking:

if (typeof dubbiya === 'undefined') {
    dubbiya = {};
}

if (typeof dubbiya.preconditions === 'undefined') {
    dubbiya.preconditions = {};
}

dubbiya.preconditions = {
    checkArgument : function(expression) {
        if (!expression) {
            throw "IllegalArgumentException";
        }
    }
};
I can use it as such:
function createRelationship(type) {
dubbiya.preconditions.checkArgument(
type === 'one_to_one' ||
type === 'many_to_many' ||
type === 'one_to_many' ||
type === 'many_to_one');
    // now do the actual stuff for the function

}
I like this because when I look at the code, I see immediately that this is type checking code, and not business logic.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.