Typescript

@doubleyou.sessions




Typescript


TypeScript is a language for application-scale JavaScript development.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
Any browser. Any host. Any OS. Open Source.



TypeScript is a language for application-scale JavaScript development.

Nos permite modularizar el desarrollo
mediante paradigmas bien conocidos 

  • static  typing
  • modules
  • classes
  • interfaces
  • enums
  • generics

TS

function Greeter(greeting: string){
    this.greeting = greeting;
}
Greeter.prototype.greet = function() {
    return "Hello, " + this.greeting;
}

var greeter = new Greeter("world");
var button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() { alert(greeter.greet()); };
document.body.appendChild(button);

JS

function Greeter(greeting) {
    this.greeting = greeting;
}
Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

var greeter = new Greeter("world");

var button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function () {
    alert(greeter.greet());
};
document.body.appendChild(button);


Claves del lenguaje


  • Alineado con ES6
  • Static Typing
  • Tooling
  • Amplio soporte de "externs"
  • Apto para trabajo en grupo
  • Portar código AS3 es sencillo
  • Desarrollado en Typescript
  • Corre en NodeJS




Instalación


$ sudo npm install typescript -g 


Compilación


$tsc source.ts 

  • código limpio y legible
  • ES5 o ES3 ( default )
  • hacia fichero único
  • hacia varios ficheros
  • AMD/CommonJS



Extensiones


  • .ts Ficheros source
  • .d.ts Ficheros de descripción ( como .h en c++ )




Type Annotation

function ( a:string, b:number, c:boolean, d:string[], e:CustomType )

Types


Todos los tipos son subtipos de "any". ( Como el * de as3 )


Primitive Types


  • number
  • boolean
  • string
  • null
  • undefined
  • typed Arrays


Typed Arrays


// normal declarationvar typedStringArray:string[] = [];var typedNumberArray:number[] = [];
// Alternate declarationvar typedNumberArray:Array<number> = new Array<number>();
// Multiple dimensional Arraysvar multiDimensionalArray:number[][];var multiDimensionalArray:CustomType[][];

Typed Functions

// Inline declarationvar callBack:()=>void;function asyncLoad( cb:( data:any, error:string )=>void ):void { ... }
// Interface declarationinterface ICallBack{ ( data:any, error:string ):void }
function asyncLoad( cb:ICallBack ):void { ... }

Associative Arrays

var typedDict:{ [name:string]:string } = [];typedDict['test'] = "Hello"; // Pass
typedDict['test'] = 10; // Fail

var typedDict:{ [name:string]:CustomClass } = [];

interface ITypedDict{ [name:string]:CustomClass; }
var typedDict:ITypedDict = [];

Fat Arrows

var c = ( e ) =>{ return e*e }
var c = e => e*e;

class A
{
    data:number = 10;
    c:(e)=>void = (e) =>{ e*e* this.data }
}   

var c = function (e) {
    return e * e;
};
var c = function (e) {
    return e * e;
};

var A = (function () {
    function A() {
        var _this = this;
        this.data = 10;
        this.c = function (e) {
            e * e * _this.data;
        };
    }
    return A;
})();





Interfaces

Custom Types


interface ILogger {} 
class Logger {} 
 
var loggerA: ILogger; 
var loggerB: Logger; 

interface IJSONResult {    result:string;    code:number;}var result: IJSONResult = { result:"World", code:200 } // Pass
var result: IJSONResult = { result:"World", code:"200" } // Fail

Inhehirance


interface A{    methodA();}
interface B extends A{ methodB();}

class C implements A, B
{
    methodA(){}
    methodB(){}
}



Method Overload


interface A{    method();    method(total:number);    method(total:string, sum?:number );}

Interface Mergin


interface I {
   foo(x: number): void;
   foo(x: string): void;
}interface I {
   foo(x: Date): void;
   foo(x: {abc: string}): void;
}
|
V
interface I {
   foo(x: Date): void;
   foo(x: {abc: string}): void;
   foo(x: number): void;
   foo(x: string): void;
}



Classes

class Greeter{
constructor() { ... } ... }

Constructor


constructor( message: string ){}
constructor( public message: string, private text:string ){}
    


Parametros opcionales

method( optionalParam?:string ){}

Valores por defecto

method( defaultValue:number = 100 ){}    



Properties


class Greeter {

    greeting: string; 
    public greeting:string;
    private _greeting:string;
    
    public static EVENT:string = "event";
    public private EVENT:string = "event";

}


Methods


...method():void{}public method():boolean{ return false; }private method():boolean{ return false; }
public static method():boolean{ return false; }private static method():boolean{ return false; }
...


Inhehirance


class A
{
    constructor(){ console.log('SUPER CONSTRUCTOR'); }
    methodA(){ console.log('SUPER METHOD A'); }
}
class B extends A
{
    constructor()
    {
        super(); // must first call super
        console.log('DERIVED CONSTRUCTOR');
        ...
    }  
    methodB(){}
}


Method Overloading



class A
{
    methodA( c:string )
    methodA( c:number )
    methodA( c:string[] )
    {
        // Debemos de comprobar nosotros los tipos    }
}

Overload on Constants


var canv = document.createElement('canvas');
    canv.getContext('2d');

Old

var canv:HTMLCanvasElement = <HTMLCanvasElement>document.createElement('canvas');
    canv.getContext('2d');

New


interface Document {
    createElement(tagName: string): HTMLElement;
    createElement(tagName: 'canvas'): HTMLCanvasElement;
    createElement(tagName: 'div'): HTMLDivElement;
    createElement(tagName: 'span'): HTMLSpanElement;
    // + 100 more
}
var canv:HTMLCanvasElement = /*infered*/document.createElement('canvas');
    canv.getContext('2d');    



Overload on Constants


interface ICustomType
{    ....    select(tag:string):HTMLElement;    select(tag:'canvas'):HTMLCanvasElement;    select(tag:'image'):HTMLImageElement;    select(tag:'custom'):CustomElement;    ....}

Enums


enum Style
{
  NONE = 0,
  BOLD = 1,
  ITALIC = 2,
  UNDERLINE = 4,
  EMPHASIS = Style.BOLD | Style.ITALIC,
  HYPERLINK = Style.BOLD | Style.UNDERLINE
}    
enum Status
{
    New,
    Active,
    Disabled
}    

Accesing Enum Data


enum TShirtSize
{
  Small,
  Medium,
  Large
}

// get enum value
var c:number = TShirtSize.Small; // 0
var d:string = TShirtSize[TShirtSize.Small]; // Small

Modules


module x
{
    module y
    {
        module z
        {
        
        }
    }
}
    
module x.y.z
{

}
    


Modules


  • Scoping of variables (out of global scope)
  • Code re-use
  • AMD or CommonJS support
  • Encapsulation
  • Don’t Repeat Yourself (DRY)
  • Easier for testing

Generics

function cast<T>( obj:any ):T
{
    return <T>obj;
}
interface A
{
    method();
}

class B implements A
{
    method(){}
}

class C{ }

function cast<T extends A>( obj:any ):T
{
    return <T>obj;
}

var a:B = cast( new B() ); // OK
var b:B = cast( new C() ); // Fail



More generics


interface Array<T>{
    ...
    map<U>(callbackfn: (value: T, index: number, array: T[]) => U): U[];
    ...
}

Object Pool

export class Pool<T>
{
        private pool:Array<T>;
        private counter:number;

        constructor(type:any, len:number)
        {
            this.pool = [];
            this.counter = len;

            var i:number = len;
            while (--i > -1)
                this.pool[i] = new type();
            return this;
        }

        public pop():T
        {
            if (this.counter > 0)
                return this.pool[--this.counter];
            else
                throw new Error("You exhausted the pool!");
        }

        public push(s:T):void { this.pool[this.counter++] = s; }
        public getPool():Array { return this.pool; }
}    



Amplio soporte en IDE


Eclipse
IntelliJ
WebStorm
Sublime 2/3
TextMate
Atom

Typescript

By Pedro Casaubon

Typescript

  • 1,172