Typescript

javascript
coffeescript

TypeScript:
https://www.typescriptlang.org/
http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript - done watching
http://stackoverflow.com/questions/12694530/what-is-typescript-and-why-would-i-use-it-in-place-of-javascript

http://www.sitepoint.com/microsoft-typescript-javascript-precompiler
https://www.sitepoint.com/introduction-to-typescript/
http://beta.slashdot.org/story/175699
https://blogs.msdn.microsoft.com/typescript/2016/09/22/announcing-typescript-2-0/

TypeScript is a superset of JavaScript that compiles to plain JavaScript.

It adds optional static types, classes, and modules.

TypeScript is open-source.

All JavaScript code is TypeScript code.  All JavaScript libraries work with
TypeScript.

TypeScript compiles to plain JavaScript.

Instead of using annotation, we have:

function process(x: string[]) {
}

x: number
x: bool
x: string
x: string[] // x is an array of string
x: () => string // x is a function that returns a string
x: {a: number; b: string;} // x is a object that has a number member and
   a string member, and these properties are named a and b.
x: any

var message:string = "Hello World";
var num:number = 12;

ES5 has objects but it has no concept of class.  ES6 introduce classes:

class LoginFormController {
  constructor() {
  }

  submit() {
  }
}

class Greeting { 
   greet():void { // Declaring a function and its return type
      console.log("Hello World!!!") 
   } 
} 
var obj = new Greeting(); 
obj.greet();

number, string, Boolean, void, null, undefined, user defined types (enums, 
classes, interfaces, arrays, tuple)

var [identifier] : [type-annotation] = value;
var [identifier] : [type-annotation]; // variable-type will be set to any.
var [identifier] = value;
var [identifier]; // declare neither value or type.

TypeScript allows changing a variable from one type to another. TypeScript 
refers to this process as Type Assertion. The syntax is to put the target type 
between < > symbols and place it in front of the variable or expression. The 
following example explains this concept:

var str = '1' 
var str2:number = <number> <any> str   //str is now of type number 

interface Thing {
  a: number;
  b: string;
}

x: Thing // x is of type Thing that we defined above.

var n = process({a: 10, b: "hello"});

TypeScript has ability to do type inference.

In TypeScript, interface are structural.

interface Thing {
  a: number;
  b: string;
  c?: bool;
}

In the above code, the question mark after c indicate that c is optional.

We can also have functions inside interface:

interface Thing {
  a: number;
  b: string;
  foo(s: string): string; // foo is a function that returns a string
}

TypeScript also support overloading inside interface:

interface Thing {
  a: number;
  b: string;
  foo(s: string): string;
  foo(n: number): number;
}

The overload above can also be rewritten as:

interface Thing {
  a: number;
  b: string;
  foo: {
    (s: string): string;
    (n: number): number;
  }
}

We can also add any attributes to a function:

interface Thing {
  a: number;
  b: string;
  foo: {
    (s: string): string;
    (n: number): number;
    data: any;
  }
}

In the above code, data is an attribute or a member property of the function
foo.  Remember that in JavaScript, functions are really objects, so function
can also have member variables or properties.

We can also have constructor functions inside interface:

interface Thing {
  a: number;
  b: string;
  foo: {
    (s: string): string;
    (n: number): number;
    data: any;
  }
  new (s: string): Element; // constructor function, take string, return Element
  [index: number]: Date; // Thing can also behave as an array.
}

In the above code, if we treat Thing as an array (access it with an index), we
get a Date object back.

function makeAccumulator() {
  var sum = 0;
  return {
    clear: function() { sum = 0; },
    add: function(value: number) { sum += value; },
    result: function() { return sum; }
  };
}

interface Accumulator {
  clear(): void;
  add(x: number): void;
  result(): number; // result is a function that take no parameter, return number
}

function makeAccumulator(): Accumulator { // Return type is Accumulator
  var sum = 0;
  return {
    clear: function() { sum = 0; },
    add: function(value: number) { sum += value; },
    result: function() { return sum; }
  };
}

class Point {
  x: number;
  y: number;
  private color: string;  
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
    this.color = "red";
  }
  dist() {
    return Math.sqrt(this.x * this.x + this.y * this.y);
  }
  static origin = new Point(0,0);
}
var p = new Point(10, 20);

THe above code compiles to:

var Point = (function() {
  function Point(x,y) {
    this.x = x;
    this.y = y;
    this.color = "red";
  }
  Point.prototype.dist = function() {
    return Math.sqrt(this.x * this.x + this.y * this.y);
  };
  Point.origin = new Point(0,0);
  return Point;
})();
var p = new Point(10,20);

Static variables go on the constructor function object.  Methods go on the
prototype chain.

In the above TypeScript code, we can have private variable, but because
JavaScript does not really have private variables, when the code is compiled to
JavaScript code, we can still modify the value of this member variable.  After
Ecmascript 6 is finalized, perhaps the TypeScript team will change their 
transpiler code to generate real private variables.

Instead of declaring member variables, and then initialize them in a constructor
function as we did above, we can shorten it a bit by eliminating the declaration
step, and adding the declaration to the constructor function using the public
keyword:

class Point {
  private color: string;
  constructor(public x: number, public y: number) {
    this.color = "red";
  }
}

In the above code, we also eliminate the initialization step inside the 
constructor function, but the generated code does not change.

We can also have default value:

class Point {
  private color: string;
  constructor(public x: number = 0, public y: number = 0) {
    this.color = "red";
  }
}

With TypeScript, a class can also extends another class:

class Point3D extends Point {
}

The generated code:

var Point3D = (function (_super) {
  __extends(Point3D, _super);
  function Point3D() {
    _super.apply(this, arguments);
  }
  return Point3D;
})(Point);

As we can see, the generated code is an IIFE that accept the base class as
the parameter _super, and it invokes the __extends function which setup the
prototypal inheritance relationship, and inside the Point3D function, the
generated code use the apply method to invoke the base class constructor.

The __extends function is provided by TypeScript.  It is the only methods that
get added to the generated JavaScript.  If you are trying to make your existing
code to work with TypeScript so that you can take advantage of TypeScript, and 
if you have an function name __extends, then you need to rename your __extends 
function to something else.

The __extends function provided by TypeScript:

var __extends = this.__extends || function(d,b) {
  function __() { this.constructor = d; }
  __.prototype = b.prototype;
  d.prototype = new __();
}

class Tracker {
  count = 0;
  start() {
    window.onmouseover = e => {
      this.count++;
      console.log(this.count);
    };
  }
}
var t = new Tracker();
t.start();

The above code corresponds to:

var Tracker = (function () {
  function Tracker() {
    this.count = 0;
  }
  Tracker.prototype.start = function () {
    var _this = this;
    window.onmousemove = function (e) {
      _this.count++;
      console.log(_this.count);
    };
  };
  return Tracker;
})();
var t = new Tracker();
t.start();

In the above code, TypeScript uses the "fat arrow" function that was introduce
to the recent ECMAScript standard.  The "fat arrow" function automatically 
retain the context object.

TypeScript also the concept of module:

module Utils {
  export class Tracker {
    count = 0;
    start() {
      window.onmousemove = e => {
        console.log(this.count);
      };
    }
  }
}
var t = new Utils.Tracker();
t.start();

The generated code for the above code:

var Utils;
(function (Utils) {
  var Tracker = (function () {
    function Tracker() {
      this.count = 0;
    }
    Tracker.prototype.start = function () {
      var _this = this;
      window.onmousemove = function (e) {
        console.log(_this.count);
      };
    };
    return Tracker;
  })();
  Utils.Tracker = Tracker;
})(Utils || (Utils = {}));
var t = new Tracker();
t.start();

Modules are open-ended.  If we add the following code:

module Utils {
  export var greeting = "hello";
}

This code get added to the existing module.

Modules can also be nested:

module Acme.Core.Utils {
}

And we can shorten the name with an import statement:

import ACU = Acme.Core.Utils;

The above modules that we referred to so far are called "Internal Modules".
I guess "Internal Modules" refers to modules that we developed ourselves.

TypeScript also have the concept of "External Modules".  Perhaps, "External
Modules" refer to modules that were developed by someone else, for example,
Node modules, underscore, jQuery, etc.

/// <reference path="node.d.ts"

import http = module("http");

export function simpleServer(port: number, message: string) {
  http.createServer((req, res) => {
    res.writeHead(200, { "Content-Type": "text/html" });
    res.write("<h1>" + message + "</h1>");
    res.end();
  }).listen(port);
}

import server = module("./server");
server.simpleServer(1337, "Greeting");

TypeScript uses the file name extension .ts

To compile TypeScript code into JavaScript, use the tsc command:

tsc hello.ts

In TypeScript, interface is also open-ended because that is what happened in
the real world.  For example, jQuery UI library adds some methods to jQuery.

TypeScript is written in TypeScript.

tsc -out ts.js -declarations typescript.js

The above command is used to compile the TypeScript compiler.  It generates
the ts.js file, and also generate the declaration file.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License