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!

  • Anonymous

    SCRIPT438: Object doesn’t support property or method ‘group’

    StronglyTyped, line 28 character 3

    IE9, Win7

    • http://leaverou.me Lea Verou

      That wasn’t in the script, it’s in the tests (console.group). Fixed now.

      As for the other issues, they’re all on Windows, right? Gah, I need to finally get around to installing a vm.

      Thanks a lot!!

  • Anonymous

    Yea! Just finished a little cross browser test on Windows 7.

    Doesn’t work in Opera 11: “Object.defineProperty is not supported so StronglyTyped will fallback to regular properties”

    And doesn’t work in any of the IEs. Also you have 404 on favicon.ico :)

    Nice script. If only there’ll be a way to turn off thet auto-insertion semicolons functionality, and turn off
    type-converting equality comparison…

    • http://leaverou.me Lea Verou

      Wait, that Opera message you’re reporting is actually intentional. Opera doesn’t support Object.defineProperty yet. Were there any other issues with it? Does it work now?

      • Anonymous

        Just re-ran everything, results:

        FF4 – OK

        Chrome 11 – OK

        Safari 5 – OK

        IE9 – OK

        IE8 –

        SCRIPT445: Object doesn’t support this action

        strongly-typed.js, line 63 character 3

        IE7 – Object.defineProperty is not supported so StronglyTyped will fallback to regular properties

        Opera –
        same as IE7

        Hope this helps!

        • http://leaverou.me Lea Verou

          Thank you so much. I know what’s causing this in IE8: It only supports defineProperty in DOM elements. I’m wondering whether it’s best to make it go the fallback way or let only the properties it supports be strongly typed. The opposite problem will exist in Safari 4 too (it supports them only on non-DOM elements).

        • Anonymous

          I would rather drop support of IE8 entirely. Don’t think it’s a good idea to have this only for DOM elements.

          I mean how many front-end devs actually develop in IE8 anyway?

        • http://www.learningtitanium.com Sharry

          We still develop for UK govt that use IE6 :(

  • http://jportal.pl shpyo

    Interesting, but IS this REALLY needed in JS? Good piece of art.

    • http://leaverou.me Lea Verou

      As I wrote in my post, it can be helpful for some people. It all depends on what your background is. If you’re coming from a language like Java, I can understand how loosely typed properties can seem dangerous at first and I’m hoping that this will help ease the transition.

      • http://twitter.com/varjs Damian Wielgosik

        It definitely won’t help them in the transition – it will cement bad behaviours that are not welcome in JavaScript.

        • http://leaverou.me Lea Verou

          So you’d prefer them to use Objective-J or GWT?

        • http://twitter.com/varjs Damian Wielgosik

          They should learn JavaScript from the beginning, completely forgetting about JAVA. I have been working with JAVA guys as JavaScript developers and they were killing this language by implementing JAVA approaches in JS which is not natural, not efficient etc. etc..

        • http://leaverou.me Lea Verou

          You can’t coerce people into learning something they don’t like. You can however help them to feel more comfortable and hope once they learn more, they won’t need helper wheels any longer.

          Also, I find it quite useful for debugging purposes actually.

        • http://twitter.com/varjs Damian Wielgosik

          So if they don’t like it, they shouldn’t be programming in JS. Your code is very nice and shows that JS is a very flexible language, but this kind of abstraction is equally dangerous and not natural like having JAVA-like classes and so. There is almost never a situation when there are only JAVA guys on the project. Very often (if not always) they work with people who know JS as their primary language and this kind of connection makes both fractions unhappy and frustrated. I even don’t want to say about inefficiency because of the additional layer.

          Btw. – if I wanted to code JAVA jumping from JS, should I implement prototypes, closures and so there to have a smooth transition? I don’t think so.Also, if somebody feels comfortable with something, it’s a very optimistic wish saying he/she will stop at some point and start using something different. I don’t get this logic at all :)Best Lea :)

        • http://leaverou.me Lea Verou

          So if they don’t like it, they shouldn’t be programming in JS.

          Hey, I used to absolutely HATE JavaScript before I learned more about it. It’s a natural human reaction when someone is out of their comfort zone.

          Your code is very nice and shows that JS is a very flexible language,

          Thanks!

          There is almost never a situation when there are only JAVA guys on the project.

          Of course we’re not talking about people working on a project, but people wanting to learn JS for various other reasons. Who would let someone with no JS experience work on a project as a JS developer anyway?

          I even don’t want to say about inefficiency because of the additional layer.

          If there are not too many objects with such properties, I don’t think it’s that much of an overhead. People learning JS don’t work on huge applications that need every ms anyway.

          Btw. – if I wanted to code JAVA jumping from JS, should I implement prototypes, closures and so there to have a smooth transition?

          I don’t think Java would let you implement prototypes and closures anyway, it’s not that flexible :P

          Also, if somebody feels comfortable with something, it’s a very optimistic wish saying he/she will stop at some point and start using something different.

          I think it makes sense to believe that once they get familiar with the language and its other differences, they would want to take advantage of its loosely typed nature.

  • Paul d’Aoust

    I’m not really a strongly-typed sort of guy myself, but I had to drop by and say that I absolutely love the logo. Brilliant concept!

    • http://leaverou.me Lea Verou

      Thank you so much!

  • Anonymous

    New hot and sexy browser tests:

    FF4 – OK

    Chrome 11 – OK

    Safari 5 – OK

    Opera – Kinda runs, but without proper errors in log. With unintelligible console.log-s it’s pretty unusable: http://imm.io/5ugT

    E9 – OK, just little mistake with spacing somehow: “LOG: o.testConst is3.141592653589793″

    IE8 – Tries to do something, then

    SCRIPT5007: Object expected

    strongly-typed.js, line 75 character 3

    IE7 – same as IE8

    • http://leaverou.me Lea Verou

      Thank you so much!

      As for Opera, I can’t do much about that, except pinging David Storey (product manager of Dragonfly) to change how DFL handles errors.

      Could you please check if the IE8- bug is fixed now?

      • http://twitter.com/suprMax Max

        Nope! New error, IE7-8:

        SCRIPT5007: Object expected

        strongly-typed.js, line 112 character 3

        http://imm.io/5uzl

        • http://leaverou.me Lea Verou

          Thank you! It’s the same error, I just moved stuff around. I think I finally fixed this one now. (?)

          I should probably add a unit test for DOM elements to see whether it will work in IE8.

        • http://twitter.com/suprMax Max

          IE7-8:

          “Getters and Setters are not supported so StronglyTyped will fallback to regular properties

          ” and

          “LOG: o.testConst is 3.141592653589793

          LOG: Attempting: o.testConst = 5…

          LOG: o.testConst is 3.141592653589793 ”

          Seems like it’s working. At least some parts. No errors whatsoever.
          (even where they should appear)

        • http://leaverou.me Lea Verou

          Thanks again!

          Hm, that’s really strange. How can constants work if properties don’t? wtf? I should definitely look into it further.

    • http://leaverou.me Lea Verou

      Btw, I reported the DFL bug and it’s been fixed. Not sure if it’s in a public build yet though. :)

  • Ashok Sudani

    Completely disagree with this blog.

    What does it matter if we assign “String” to variable at one time, and “Integer” at the second time .. If language itself is handling all these dynamic stuffs naturally and not creating any memory leak / other problems????

    This library would do nothing than adding overhead to page.

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries - Smashing Magazine

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries. « Coding Languages

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | Blogs – NG Outsourcing

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | Joomla Showcase : CSS Showcase

  • Pingback: Smashing Magazine Useful HTML-, CSS- and JavaScript Tools and Libraries | Synergetic Blog

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | test2

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | Ruturaj Pradeep Kohok | Your Web Advisor

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries dari Achmatim.Net

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | IdentityNepal.com

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | Remake Wordpress Theme

  • Pingback: JavaScript Magazine Blog for JSMag » Blog Archive » News roundup: yokul, Log.io, hook.io, Why JavaScript haters should learn JavaScript

  • Pingback: test1 » Blog Archive » Useful HTML-, CSS- and JavaScript Tools and Libraries

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | CS5 Design

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | N - DESIGNS |

  • Pingback: A polyfill for HTML5 progress element, the obsessive perfectionist way | Lea Verou

  • Anonymous

    To quote Steve Yegge (who is smarter than your boyfriend):

    “It should be pretty obvious that dynamic + optional static types is a
    better approach than static + optional dynamic features. The latter is
    premature optimization, plain and simple: the root of all evil.”

    So good call on making this library but shame on your Java-coding (pfft) boyfriend for his opinionated assertions.

  • http://eligrey.com Eli Grey

    You may be interested in my go attempt strict typing in JS, though it only works in Mozilla JS engines. It’s a little outdated and lacking support for WebGL typed arrays.

    • http://leaverou.me Lea Verou

      I am, where is it? :)

      • http://eligrey.com Eli Grey

        Oh, it appears that DISQUS stripped my link. It’s https://gist.github.com/337199 and I just added the WebGL stuff, along with some of the base DOM types.

        Edit: Apparently it wasn’t stripped; your CSS just doesn’t prominently expose links in comments with color (you should look into changing that).

        • http://leaverou.me Lea Verou

          Nice work, and much shorter than mine! Why does it only work in Moz?

        • http://eligrey.com Eli Grey

          It uses JavaScript 1.8 (implicit returns) and 1.7 (let scope, destructuring assignment), and only Mozilla’s JS engines support those. Other engines are ECMAScript engines, and it wouldn’t make sense to start implementing non-ECMAScript features. What’s nice is that many JS 1.6+ features are making their way into ECMAScript Harmony, though if you have access to an ECMAScript Harmony engine, you don’t need this script as there’s optional strict typing built-in to the language.

        • http://leaverou.me Lea Verou

          Oh, I thought those were implemented in other browsers too by now. Lameage (for them, not your script) :(

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | Tekki Web Solutions

  • http://www.kaltechsolutions.com website development

    Hi,
    in the article there are orange color boxes with text on it how did you created this?

  • Alex C.

    Hi Lea,

    We recently created an open source project
    called ‘Strongly-Typed Javascript’. While looking for references to this
    domain, I got to your blog post related to this subject. 

    Well our approach is
    to write the code directly in Java (much better IDE support) and then generate
    the corresponding JavaScript. What’s new in our approach compared to similar
    projects (GWT for example) is that the generated Javascript is very predictable
    and clean, as similar as possible to the Java code so that the debugging in the
    browser is quite easy.  The number of new
    methods to learn in order to use the library it’s less than 20! The rest is
    basic Javascript. 

    We propose also a bridge to jQuery (and jQuery UI), but it’s
    quite easy to add bridges to other libraries. 

    If you’re interested, please have
    a look on the project’s website http://st-js.sourceforge.net

  • http://www.rackmountsales.com/Cat5_KVM_Switches_s/56.htm USB KVM

    It’s always amazing to me to see how new technology is
    adopted by influencers you define here about strongly typed. I am experiencing
    the same slowness and unresponsiveness on using of API. Lucidity in your post
    is basically remarkable and I can presuppose you are a proficient on this
    field. I’ll attempt to visit more frequently to increase my knowledge here.

     

  • http://www.facebook.com/profile.php?id=631862022 Yves Wheeler

    The only reason I’d use strong typing in Javascript is if it gave a performance boost, I seriously doubt that this library would do that. I’m hoping one day that browser vendors will make strong typing an optional feature, especial if Adobe plan to deprecate Flash in favour of HTML5. Flash still bench marks better then HTML5.

  • afshin

    Ow, that’s cool but I believe the key feature of JavaScript (or any other scripting languages) is to use dynamic types.

  • Richard Knop

    I don’t think it makes much sense. One of the key strengths of JavaScript is its dynamic typing (other one is the fact that function are first class citizens, closures etc). By introducing static typing you lose some expressive power of JavaScript. This will also introduce bad behaviour and practices. I recommend not to use this library.

  • Pingback: Useful HTML-, CSS- and JavaScript Tools and Libraries | Smashing Magazine