StronglyTyped: A library for strongly typed properties & constants in JavaScript

StronglyTypedI’ll start by saying I love the loosely typed nature of JavaScript. When I had to work with strongly typed languages like Java, it always seemed like an unnecessary hassle. On the contrary, my boyfriend even though very proficient with HTML, CSS and SVG, comes from a strong Java background and hates loosely typed scripting languages. So, to tempt him into JS and keep him away from heavy abstractions like Objective-J, I wrote a little library that allows you to specify strongly typed properties (and since global variables are also properties of the window object, those as well) of various types (real JS types like Boolean, Number, String etc or even made up ones like Integer) and constants (final properties in Java). It uses ES5 getters and setters to do that and falls back to regular, loosely typed properties in non-supporting browsers.

Also, as a bonus, you get cross-browser Function.prototype.bind and Array.prototype.forEach and a robust type checking function: StronglyTyped.is(type, value).

Example: Strongly typed properties

You define strongly typed properties by using the corresponding methods of the StronglyTyped object. For example, the following snippet defines a boolean property called “foo” on an object literal:

var o = {};

StronglyTyped.boolean(o, 'foo', true);

console.log(o.foo); // prints true

o.foo = false;
console.log(o.foo); // prints false

o.foo = 'bar'; // TypeError: foo must be of type Boolean. bar is not.

Example: Constants

You define constants by using the constant method of the StronglyTyped object. For example, the following snippet defines a global MAGIC_NUMBER constant:

var o = {};

StronglyTyped.constant(window, 'MAGIC_NUMBER', 3.1415926535);

console.log(MAGIC_NUMBER); // prints 3.1415926535

MAGIC_NUMBER = 4;
console.log(MAGIC_NUMBER); // prints 3.1415926535

Please note that constants only become read-only after they first get a non-undefined value. For example:

StronglyTyped.constant(window, 'MAGIC_NUMBER');

console.log(MAGIC_NUMBER); // prints undefined

MAGIC_NUMBER = undefined;

console.log(MAGIC_NUMBER); // prints undefined

MAGIC_NUMBER = 3.1415926535;
console.log(MAGIC_NUMBER); // prints 3.1415926535

MAGIC_NUMBER = 4;
console.log(MAGIC_NUMBER); // prints 3.1415926535

Supported types

The property types currently supported by StronglyTyped are:

  • Array
  • Boolean
  • Date
  • Function
  • Integer
  • Number
  • RegExp
  • String

null and undefined are valid in every type. NaN and Infinity values are accepted in both the Number and the Integer types.

If you want to use a type that’s not among the above but either is native to the browser (for example Element) or a global object, you can use the generic method StronglyTyped.property(type, object, property [, initialValue]):

var o = {};

StronglyTyped.property('Element', o, 'foo', document.body);

console.log(o.foo); // prints a representation of the <body> element

o.foo = document.head;
console.log(o.foo); // prints a representation of the <head> element

o.foo = 5; // TypeError: foo must be of type Element. 5 is not.

Browser support

It should work on every browser that supports Object.defineProperty or __defineGetter__ and __defineSetter__. As you can see from kangax’s awesome compatibility tables for Object.defineProperty and __define(G|S)etter__, those are:

  • Firefox 3.5+
  • IE8 (only on DOM elements)
  • IE9+
  • Opera 10.5+
  • Chrome 5+
  • Safari 4+
  • Konqueror 4.4+

However, it’s only verified to work in:

  • Firefox 4 (Win and OSX)
  • IE9+
  • Opera 11.10 for OSX, Opera 11 for Windows
  • Chrome (Win and OSX)
  • Safari 5 (Win and OSX)

This doesn’t mean it won’t work in the rest, just that it hasn’t been tested there (yet). You can load the unit tests (sort of…) in a browser you want to test and let me know about the results. 🙂

Naice! Can I haz?

As usual, you can get it from Github: Github repo

Credits

Thanks a lot to Max (@suprMax) for Windows testing!