Friday, May 24, 2013

TypeScript, CRM 2011, and You

Those who know me closely know that I hold a certain disdain for JavaScript.  Not because I’m particularly bad at it (though some of my public and private code might put that to question), but because I believe I’m good at it.

One thing that has always bothered me is how difficult it is to manage data structure contracts (read: types), throughout a large amount of code.  To achieve application-level fidelity, you need a specialized library, that calls for specialized object factories—breaking away from all native syntax, and making useful documentation generation and structure a miserable chore.  At least, that’s what it’s been for me.

It didn’t have to be this way, but is.  Take, for example, the nearly useless “typeof” operator.  At some point, somebody on the JavaScript language development team thought that types could be important, and then promptly died before his thought could infect other web developers.

That’s what development comes down to for me:  data contracts.  Value or variable-based, I care not.  But, I want strong ones, flexible ones, abstracts, interfaces, inheritance, and predictability.  JavaScript developers either make their livings, or ruin their lives, by writing to edge-cases—and in JavaScript API development, it’s all edges, all the way down.  If strong types were possible, I speculate that you could cut the jQuery library, for example, in half. 

Whatever the shortcomings, they’re neither here nor there.  Because JavaScript only hit puberty in 2009, and it is still evolving.  Its ubiquity is undeniable, and its adoption and enrichment are accelerating.  Because of its slow maturity, it can pick and choose from more mature languages to implement advanced concepts.  This, of course, is driven from the myriad of developers that leave their comfort zones (perhaps reluctantly) to dive into this wishy-washy world of “nearly anything goes.”

Let’s face it: IDEs give JavaScript developers most of their power. IntelliSense’s own JavaScript support has made leaps and bounds in recent iterations.  Still, most of the enrichment and “type” inference comes from documentation comments, in either the VSDoc or JSDoc formats.  Its native introspection capabilities, however, are like Reflector on meth-addicted steroids.  At runtime, you can achieve things that make .Net bleed with envy.

The question, for me, has always been about bridging the gap: how do I posit stronger typing into my development, if not the language?  At first, I was drunk with prototypes and closures, and tried to produce my own typing/inheritance model.  Its quirks and desperate lack of syntactic approximation to stronger-typed languages left me to abandon it for something else.

In my search, I’ve encountered a couple of strong contendersDart is a promising project, and may go somewhere, but TypeScript appears syntactically closer to ECMA Script 6 (which will ultimately replace the current iteration of JavaScript).  The ECMA draft specification doesn’t appear to do much for type management, unfortunately—but that would be a major paradigm shift for JavaScript at this stage.  And honestly, I see TypeScript as the stepping stone to it.

The big reason I hope this, is that all valid JavaScript is inherently valid TypeScript.  Meaning that I don’t need an interop library to implement rich and mature JavaScript libraries, nor to I have to cross-compile them into some alternate representation.  However, TypeScript benefits strongly from “definition” files, which help provide type associations to improve the TypeScript experience of those libraries.  I’m proud to announce today, that I have helped with two such definitions for use with Dynamics CRM 2011:

  1. Definition file for the Microsoft Xrm JavaScript namespace:
  2. Definition file for the XrmServiceToolkit project: 
    (you might have to get it from the Source: Scripts\typescript\XrmServiceToolkit.d.ts)

I use these two together often, coupled with internal definition files for jQuery, JSON, and other common libraries.  The stock definition files have done a great job, so these are the only two new ones that I’ve needed, so far.  (Though, now that I’m getting into KendoUI, I’d love to see definition files for it.)

This is all well and good, but how is it supposed to help you?  There are many good arguments surrounding the adoption of TypeScript, and other MVPs have addressed it in various venues.  Personally, I take the following benefits, over raw JavaScript development:

  • Types!  (If that wasn’t the first thing on this list, I should be soundly questioned.)
  • Compiles to JavaScript by basically removing itself from the code, and applying some cohesive closure structures to the results.  (This is why all valid JavaScript is valid TypeScript.)
  • C#’s interface and inheritance model!  (Multiple inheritance isn’t supported, but multiple interfaces are.  My C++ days are calling, and I let it go to voicemail.  I’m ok with this model.)
  • Multiple method signatures!  (This doesn’t apply anything on the “compile” to JavaScript—yet—but makes the IDE experience nicer.)
  • Generics!  (…coming in TypeScript 0.9)

These are all concepts I encounter daily in my C# coding, and it’s nice to finally have a way to express them in my JavaScript development, without getting in my own way, or doubling the amount of work necessary to apply it.  However, as John Petersen recently expressed in CODE Magazine, “TypeScript compiles to pure JavaScript but that isn’t a license for ignorance about how JavaScript works.”

So, if you want to start learning TypeScript, the best way to start is to do the following:

  1. (Optionally) Read the TypeScript language specification (but then, I’m into things like that)
  2. Install the TypeScript plugin for Visual Studio (build support)
  3. Install the Web Essentials add-in for Visual Studio (IntelliSense support—very basic, currently, but will identify errors at design-time)
  4. Follow the Quick Start guide for TypeScript (to learn syntax basics)

I find the following tweaks to Visual Studio’s options handy:

  • Text Editor\TypeScript\Project: Uncheck all “Compile on Save” options; These collide with Web Essentials, and I prefer to use the “Build” action anyway.
  • Web Essentials\TypeScript
    • “Compile to EcmaScript 3”:  False
    • “Add generated files to project”:  True
    • “Compile all TypeScript files on build”:  True
    • “Compile TypeScript on save”:  False (But, if you want to, use this option, instead of the one from the TypeScript plugin—for now.)
    • “Show preview window”:  False (This one just gets in my way, and is only really useful if you set the “compile on save” option.)

Then, you can use reference tags in your own TypeScript files, to include the definition files from above and start enjoying TypeScript in CRM 2011 development:

/// <reference path="definitions/Xrm2011.d.ts" />
/// <reference path="definitions/XrmServiceToolkit.d.ts" />

I hope you’ll be as interested in TypeScript as I am, because it’s a fantastic, open-source initiative from Microsoft—and it’ll prepare you for the next generation of JavaScript interpreters.

No comments:

Post a Comment

Unrelated comments to posts may be summarily disposed at the author's discretion.