- A superset of the JavaScript language.
- Code in TypeScript, compile to JavaScript, deploy JavaScript. (Similar workflow to CoffeeScript)
- Very similar to JavaScript.
- Type safety - when you need it. TypeScript is a gradually typed language.
- Less boilerplate.
- Programmer's intent is clearer in the code.
- Easy to start using: Install the compiler, turn on filewatcher, rename a *.js file to *.ts and add type markup at your lesiure.
- Easy to stop using: Delete the *.ts file, continue editing the *.js file.
http://www.typescriptlang.org/#Download
-
Node
npm install -g typescript
-
Webstorm (latest version)
A primitive type is a number, bool, string or void.
function showSum(x, y){
alert(x + " + " + y + " = " + (x+y));
}
showSum(5, "7");
This is an ordinary peice of JavaScript. But it doesn't work as intended.
function showSum(x : number, y:number){
alert(x + " + " + y + " = " + (x+y));
}
showSum(5, "7");
By adding the type annotation, the programmer's intent is clearer, and the compiler can check if the right arguments are being passed.
Creating an interface for the argument to showSum:
interface Addends{
x:number;
y:number;
}
function showSum(a:Addends){
alert(a.x + " + " + a.y + " = " + (a.x + a.y));
}
showSum({y:2, x:5});
An interface is a type that defines the property names expected on an object instance (and their types).
A class is also a type. There is an example of this later.
There are a number of ways in which TypeScript helps reduce the amount of code you have to type:
Functions can be declared shorthand:
interface Addends{
x:number;
y:number;
}
var showSum = (a:Addends) => alert(a.x + " + " + a.y + " = " + (a.x + a.y));
showSum({y:2, x:5});
You can stop typing "function" so much! Multiple arguments and statements are supported:
var alertBoth = (s1:string, s2:string) => {alert(s1);alert(s2);};
Class declarations are a formal part of the language. TS generates the appropriate JS:
class Adder {
x : number;
y : number;
constructor(x:number, y:number){
this.x = x;
this.y = y;
}
getSum(){
return this.x + this.y;
}
showSum(show : (string)=>void){
show(this.x + " + " + this.y + " = " + this.getSum())
}
}
var a = new Adder(2, 3);
a.showSum(s => alert(s));
This declared a class named "Adder" with the fields x
and y
, and a constructor that set these fields, and two methods, getSum
and showSum
. Note the equivalent javascript that TS generates.
The "module" keyword creates a namespace:
module Mathematics{
export class Adder {
x : number;
y : number;
constructor(x:number, y:number){
this.x = x;
this.y = y;
}
getSum(){
return this.x + this.y;
}
showSum(show : (string)=>void){
show(this.x + " + " + this.y + " = " + this.getSum())
}
}
}
var a = new Mathematics.Adder(2, 3);
a.showSum(s => alert(s));
The compiler has an AMD mode too!
There are no formal abstract classes or methods in TypeScript, but you can create a method whose base implementation throws.
There are properties and "private" fields:
class Adder {
private x : number;
private y : number;
constructor(x:number, y:number){
this.x = x;
this.y = y;
}
get sum(){
return this.x + this.y;
}
showSum(show : (string)=>void){
show(this.x + " + " + this.y + " = " + this.sum)
}
}
var a = new Adder(2, 3);
//compiler warning, runtime set value
a.x = -10;
a.showSum(s => alert(s));
Classes can extend other classes:
class Operation {
x : number;
y : number;
operatorText:string;
constructor(x:number, y:number, operatorText:string){
this.x = x;
this.y = y;
this.operatorText = operatorText;
}
operate():number{
throw "abstract method not implemented";
}
showOperation(show : (string)=>void){
show(this.x + " " + this.operatorText + " " + this.y + " = " + this.operate())
}
}
class Subtractor extends Operation {
constructor(x:number, y:number){
super(x, y, "-");
}
operate(){
return this.x - this.y;
}
}
var a = new Subtractor(11, 4);
a.showOperation(s => alert(s));
This created a class named Operation
, which holds some fields and knows how to show itself, and a class named Subtractor
which extended Operation to provide specific implementation details.
IMO, one of the most disappointing aspects of TS is how you can't use another framework's own special brand of inheritance.
Polymorphism can be class based:
class Operation {
x : number;
y : number;
operatorText:string;
constructor(x:number, y:number, operatorText:string){
this.x = x;
this.y = y;
this.operatorText = operatorText;
}
operate():number{
throw "abstract method not implemented";
}
showOperation(show : (string)=>void){
show(this.x + " " + this.operatorText + " " + this.y + " = " + this.operate())
}
}
class Subtractor extends Operation {
constructor(x:number, y:number){
super(x, y, "-");
}
operate(){
return this.x - this.y;
}
}
function alertOperation(o:Operation){
o.showOperation(s => alert(s));
}
alertOperation(new Subtractor(11, 4));
The alertOperation function can take any class that inherits from Operation, and we're providing it with a Subtractor.
Polymorphism can be interface based:
interface CanShowOperation{
showOperation(show : (string)=>void);
}
class Operation implements CanShowOperation {
x : number;
y : number;
operatorText:string;
constructor(x:number, y:number, operatorText:string){
this.x = x;
this.y = y;
this.operatorText = operatorText;
}
operate():number{
throw "abstract method not implemented";
}
showOperation(show : (string)=>void){
show(this.x + " " + this.operatorText + " " + this.y + " = " + this.operate())
}
}
class Subtractor extends Operation {
constructor(x:number, y:number){
super(x, y, "-");
}
operate(){
return this.x - this.y;
}
}
function alertOperation(o:CanShowOperation){
o.showOperation(s => alert(s));
}
alertOperation(new Subtractor(11, 4));
The alertOperation function can take any object that implements the properties of the CanShowOperation interface, and we're providing it with a Subtractor. Note that Operation doesn't have to explicitly implement CanShowOperation.
Type Definition files (*.d.ts) are for holding definitions but not implementations. They are usually used to create TS definitions for existing JS code. For example, here's the type definitions for Underscore.
It's often handy to pull in some definition files for the library you're using. Definitely Typed is a good one.
0.9 Alpha has just come out. It features:
-
Generics (just like java or C#)
-
Constant overloads
interface Document { createElement(tagName: string): HTMLElement; createElement(tagName: 'canvas'): HTMLCanvasElement; createElement(tagName: 'div'): HTMLDivElement; createElement(tagName: 'span'): HTMLSpanElement; // + 100 more }