6 Ways You Win With Typescript

October 29, 2012 at 10:50 AMAdministrator

Perhaps a bit behind the wave on posting about Typescript, but I wanted to take the time to get as familiar as possible with the language and tools before weighing in.  After spending some time with it, I have to say I see no downside to using it in your web applications and I’ve identified the below ways you win by putting Typescript to use in your projects.

 

No Unlearning Of JavaScript or Learning a New Language

Typescript is a superset of JavaScript which is a unique approach to the problem when compared to something like Coffee Script.  This means you can continue to use all you already know about JavaScript and only need to learn what Typescript adds to the language.  In the end, all your Typescript compiles down to regular JavaScript which makes debugging much easier.

 

Familiar OO Concepts

There are some very talented web developers out there. Many have been using JavaScript for a very long time and have learned the idiosyncrasies of the language and how to make it mimic some object oriented behaviors by using closures and the like.  Recently, however, Microsoft has been nudging those of us developing with their tools more toward HTML5 and JavaScript.  This means that many of us are coming from an OO background and the related concepts are familiar to us.  We’re going to be more productive using these concepts.

See the below example taken from the Typescript template default script file.

Typescript Example
  1. class Greeter {
  2.     element: HTMLElement;
  3.     span: HTMLElement;
  4.     timerToken: number;
  5.     
  6.     constructor (element: HTMLElement) {
  7.         this.element = element;
  8.         this.element.innerText += "The time is: ";
  9.         this.span = document.createElement('span');
  10.         this.element.appendChild(this.span);
  11.         this.span.innerText = new Date().toUTCString();
  12.     }
  13.  
  14.     start() {
  15.         this.timerToken = setInterval(() => this.span.innerText = new Date().toUTCString(), 500);
  16.     }
  17.  
  18.     stop() {
  19.         clearTimeout(this.timerToken);
  20.     }
  21.  
  22. }
  23.  
  24. window.onload = () => {
  25.     var el = document.getElementById('content');
  26.     var greeter = new Greeter(el);
  27.     greeter.start();
  28. };

 

The class definition is being used in this example and the similarities with an OO language are evident.  Note that the class also can contain a constructor.  For me, this allows the same code file per class paradigm to be used that I’m familiar with when used in conjunction with the module keyword we’ll look at in a minute.  Notice, too, how the start and stop methods are defined.  Again, familiar to a C# developer.

Compare the above with the below JavaScript which is the result after compiling.

JavaScript Example
  1. var Greeter = (function () {
  2.     function Greeter(element) {
  3.         this.element = element;
  4.         this.element.innerText += "The time is: ";
  5.         this.span = document.createElement('span');
  6.         this.element.appendChild(this.span);
  7.         this.span.innerText = new Date().toUTCString();
  8.     }
  9.     Greeter.prototype.start = function () {
  10.         var _this = this;
  11.         this.timerToken = setInterval(function () {
  12.             return _this.span.innerText = new Date().toUTCString();
  13.         }, 500);
  14.     };
  15.     Greeter.prototype.stop = function () {
  16.         clearTimeout(this.timerToken);
  17.     };
  18.     return Greeter;
  19. })();
  20. window.onload = function () {
  21.     var el = document.getElementById('content');
  22.     var greeter = new Greeter(el);
  23.     greeter.start();
  24. };

It’s possible to create a construct in pure JavaScript that behaves the same as the Typescript class, but look at how much more complicated the syntax is.  The constructor has been replaced by an inner function and the method definitions make use of the prototype pattern.

ECMAScript 6 Features Today

I have seen negative feedback about Typescript from people who are pushing back on changes to their beloved JavaScript language.  Truth is, many of the additions Typescript makes to the language, such as lambdas and modules are already proposed for ECMAScript 6 and Typescript is making them available for developers to use today.

Code Organization

I’ve mentioned the module keyword a couple of times already.  This is a powerful construct that allows the developer much more flexibility in how they organize their script files in their projects.  Below is an example of defining module and exporting a class form it.

Module with Export
  1. module Sayings {
  2.     export class Greeter {
  3.         greeting: string;
  4.         constructor (message: string) {
  5.             this.greeting = message;
  6.         }
  7.         greet() {
  8.             return "Hello, " + this.greeting;
  9.         }
  10.     }
  11. }
  12. var greeter = new Sayings.Greeter("world");
  13.  
  14. var button = document.createElement('button')
  15. button.innerText = "Say Hello"
  16. button.onclick = function() {
  17.     alert(greeter.greet())
  18. }
  19.  
  20. document.body.appendChild(button);

Here, a module called “Sayings” is being defined and a class named “Greeter is being exported from it.  This means that we can access the Greeter class by specifying “Sayings.Greeter”.  This is an example of what Typescript calls an “internal module”.  That is a module that is explicitly defined in the code.  A second kind of module is an “external module”.  There are modules that are implicitly defined in a separate file and are referred to by the file name.  Here is an example from the Typescript documentation.

In File main.ts:
      import log = module("log");
       log.message("hello");
In File log.ts:
      export function message(s: string) {    
            console.log(s);
      }

In the log.ts file, a single function is being exported (made visible outside the module).  In main.ts, the file log.ts is being imported as a module and the exported method is being called.  When you import an external module, its code is physically copied into the file as an internal module.  Note that the log module is being imported by file name.  In fact, the module name can contain an absolute or relative path such as “C/myproject/script/logger/log” or “./logger/log” where a path that begins with “.” or “..” is determined to be a relative path.  This means that you can organize your source files in a hierarchical folder structure like you would in C# and then import them using the relative path similar to how you would use a namespace. 

Better Tooling Support

Intellisense for a dynamic language is hard to do.  Since you don’t need to specify a type when declaring a variable, when you the variable name followed by a dot, what should intellisense show you?  Over the past few versions of Visual Studio, Microsoft has attempted to populate intellisense in useful ways, but there are so many scenarios where it’s just impossible to make even an educated guess about what members might be on a type.  In Typescript, if I enter the following

Intelli-1

After typing the dot after the variable name “foo”, there is not attempt to display intellisense.  After all, what is foo and what members does it have?  However, if I specify a type for the variable such as Typescript allows, I get much more useful tooling.

Intelli-2

Not only do I now have intellisense, it also displays the the members of the string type which are what apply in this situation.  It isn’t necessary to specify types for everything.  The typescript compiler goes to great lengths to try and infer the types in your code where they are not specified.  For example, if you assign the result of a function that returns a string to a variable, that variable will be considered a string.  Likewise, if I had initialized the foo variable to a value of “”, it would also have been inferred to be a string.

Type Checking at Compile Time

JavaScript does not support runtime type checking and Typescript does not add this.  However, at compile time, if the Typescript compiler can determine the type of a variable either because the type was explicitly specified or it was inferred, the use of that variable will be checked.  This check occurs one time when your ts files are compiled.  You can still shoot yourself in the foot at runtime using the dynamic features of JavaScript, but the type checking the compiler gives you brings you one step closer to bug-free code.

 

Conclusion

This has not been an attempt to exhaustively cover the features of Typescript but simply a post to point out some of the advantages of using it.  I hope to post more about specific features and their use in the near future.

Posted in: .Net | ASP.Net | JavaScript | Typescript

Tags: , , ,

An Introduction to KnockoutJS for XAML Developers

December 17, 2011 at 6:58 PMAdministrator

I've recently been working with KnockoutJS and have found it to be a very comfortable paradigm to use in constructing a web site.  Having worked with XAML a good bit over the last few years, the benefits of MVVM have been made apparent to me time and again and the approach is familiar.

KnockoutJS lets you use very nearly the same MVVM approach you're used to using in WPF or Silverlight development.  I've attached a sample application, below.  Let's have a look at it.

If you run the sample application, you'll see the following web page open in the browser.

RunningApp

There is an editable table that allows the user to edit existing contacts. Clicking the Add Contact button adds a new blank row to the table.

The ViewModel

The project contains a Javascript file named ViewModel.cs, in the Scripts directory.  The contexts of this file are listed below.

   1:  var viewModel = {
   2:      contacts : ko.observableArray([
   3:          { firstName : "Bob", lastName : "Marley" },
   4:          { firstName : "Larry", lastName : "The Cable Guy" },
   5:          { firstName : "Maxwell", lastName : "Smart" }
   6:      ]),
   7:   
   8:      addContact : function() {
   9:          this.contacts.push( { firstName : "", lastName : "" } );
  10:      }
  11:  }
  12:   
  13:  $(document).ready(function() {
  14:      
  15:      ko.applyBindings(viewModel); 
  16:  })
 
 

In the first code block, lines 1 – 11, we create a view model.  In WPF or Silverlight, out view model would contain properties and commands that we could bind to in our view.  The same is true with KnockoutJS.  Here, we have a property that is a collection of contacts and a function (command).  In lines 13 – 16, we ask Knockout to parse our view and connect the data bindings to our view model.

Notice that our property is an instance of an observableArray.  In XAML data binding, we have the concept of  the view and view model communicating with one another where events are raised when values change so that data and the controls bound to it stay in sync.  This same functionality is encapsulated in the observableArray for arrays and observable for simple properties.    So, modifying a bound property from the view model will cause a control in the view that is bound to the property to change, as well.  The reverse is also true, modifying the contents of the control will update the view model property.

The View

   1:  @{
   2:      Layout = null;
   3:  }
   4:   
   5:  <!DOCTYPE html>
   6:  <html>
   7:  <head>
   8:      <title>Index</title>
   9:      <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
  10:      <script src="../../Scripts/jQuery.tmpl.js" type="text/javascript"></script>
  11:      <script src="../../Scripts/knockout-1.2.1.js" type="text/javascript"></script>
  12:      <script src="../../Scripts/ViewModel.js" type="text/javascript"></script>
  13:  </head>
  14:  <body>
  15:      <div>
  16:          <fieldset>
  17:              <legend>Email Addresses</legend>
  18:   
  19:                  <table>
  20:                  <thead>
  21:                      <tr>
  22:                          <th>First Name</th>
  23:                          <th>Last Name</th>
  24:                      </tr>
  25:                  </thead>
  26:                  <tbody 
  27:                    data-bind='template: { name: "contactRowTemplate", foreach: contacts }'>
  28:                  </tbody>
  29:              </table>
  30:   
  31:              <button data-bind="click: addContact">Add Contact</button>
  32:   
  33:              <script type="text/html" id="contactRowTemplate">
  34:                  <tr>
  35:                      <td><input class="required" 
  36:                          data-bind="value: firstName, uniqueName: false"/></td>
  37:                      <td><input class="required" 
  38:                          data-bind="value: lastName, uniqueName: false"/></td>
  39:                  </tr>
  40:              </script>
  41:   
  42:          </fieldset>
  43:      </div>
  44:  </body>
  45:  </html>
 

We start by setting up our html table.  All probably looks familiar up to line 27.  In Xaml, we use Binding expressions to state what we want to bind to and how that binding is to behave.  KnockoutJS uses the "data-bind" attribute to specify these bindings.  In line 27 a binding is expresses that says, "for each item in the collection of contacts on the view model, create and populate an instance of the template named 'contactRowTemplate'".  You can see the template definition in lines 33 – 40.

Compare this binding with a similar Xaml binding and you'll find:

  • It's possible to do an ItemsSource type binding in KnockoutJS where an item is generated for each entry in an array.
  • Adding or removing an item from the array causes row corresponding to that item to appear or disappear respectively.
  • A template can be specified for how each item in the list will be constructed.  Compare this with the ability to specify an ItemTemplate in Xaml (note that you can organize the container of the list as you wish which is very similar to ControlTemplate's.
  • In Xaml, the data context flows in a predictable way through all an item's sub-items.  Note that the binding on the <tbody> element is to an array and the bindings inside the template are to a single item in the array.  This behaves the same as in Xaml.

The button in line 31 uses a click binding to bind the click event to the function we defined on our view model.

Yes, the binding syntax is different and there are many more binding types available than are used in this simple sample, but the library is very well documented here and the familiarity of the MVVM approach to constructing a UI make KnockoutJS a very easy library to get started with.

Download File - KnockoutSampleSolution

Posted in: .Net | ASP.Net | JavaScript | Silverlight | WPF

Tags: , , , ,

What is a JavaScript Closure, Anyway?

December 10, 2011 at 2:15 PMAdministrator

Back in the late nineties, during the .com boom, I worked on a huge web application that used XmlHttp (now known as AJAX) and extensive lots of JavaScript.  The language and how it's perceived has changed a lot since then and so has the maturity of the community using it.  Techniques have come about that make JavaScript easier to use in large internet applications.  Most of these techniques have come about because developers are learning to go with the flow of the language instead of fighting it; to use the unique qualities of the language to advantage.

An Example

Consider the following JavaScript:

   1:  function MyClass(x) {
   2:     var Addend = x;
   3:   
   4:      return AddTo = function (y) {
   5:          return y + Addend;
   6:      }
   7:  }
   8:   
   9:  var AddToTen = MyClass(10);
  10:  alert(AddToTen(10));
  11:   
  12:  var AddToFive = MyClass(5);
  13:  alert(AddToFive(10));

Beginning in line 1, a function is being defined.  Inside this function, we define a local variable and set its value equal to the passed in parameter.  Then, an inner function is returned.  This inner function refers to the local variable defined in the outer function.  Once the outer function has completed execution, it cannot be garbage collected because it is still being referred to by the inner function.  It's also very important to understand that whatever value the local variable has at the time the inner function is returned, is the value that will be visible to the inner function when it is executed from an external call.

When lines 9 and 10 run, 10 is passed in to the outer function and the local variable is set to 10.  When the inner function is returned, it will always see Addend as having the value of 10.  Thus, this script will pop the first alert with a value of 20 and then a second with the value of 15. 

In short, whenever an inner function is returned from an outer one, a logical copy of the outer functions state is made available to the inner function and this state can be accessed each time the inner function is invoked.

What About a .Net Example

We can duplicate this behavior in C#.  I created a Console application to illustrate this.

    class Program
    {
        static void Main(string[] args)
        {
            var five = MyMethod(5);
            Console.WriteLine(five(10));

            var ten = MyMethod(10);
            Console.WriteLine(ten(10));
            Console.ReadLine();
        }

        static Func<int, int> MyMethod(int x)
        {
            int addend = x;

            return new Func<int, int>((y) =>
            {
                return addend + y;
            });
        }
    }

Posted in: .Net | ASP.Net | JavaScript

Tags: , ,