TypeScript

Luis Aviles
@luixaviles

TypeScript

JavaScript that scales

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

Any browser. Any host. Open source

TypeScript

Installation

npm install -g typescript

TypeScript

Overview

Overview

  • Developed and Maintained by Microsoft
  • Introduced in October 2012 by Ander's Hejlsberg

 

Anders Hejlsberg is a prominent Danish software engineer who co-designed several popular and commercially successful programming languages and development tools. He was the original author of Turbo Pascal and the chief architect of Delphi.

TypeScript

  • Free & Open Source

TypeScript

  • ECMA standards
  • Superset of JavaScript

TypeScript

  • Becoming an Industry Standard
  • Used in Angular implementation
  • Build plugins available
    • Grunt
    • Gulp

Who is using TypeScript?

ES2015

What is ES6?

  • Known as ECMAScript 2015
  • Is the latest version of ECMAScript standard
  • ES6 is a significant update to the language
  • First update to the language since ES5 was standarized in 2009

ES6 Features

Default Parameters

var link = function (height, color, url) {
    var height = height || 50;
    var color = color || 'blue';
    var url = url || 'http://www.google.com';
}
var link = function(height = 50, 
                    color = 'blue', 
                    url = 'http://www.google.com') {
    // Write your business logic here
}

ES6 Features

LET: Alternative to declare a variable with "var"

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

ES6 Features

LET: Alternative to declare a variable with "var"

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  }
  console.log(x);  // 1
}

ES6 Features

Arrow Functions

var _this = this;
$('.btn').click(function(event){
  _this.sendData();
})
$('.btn').click((event) =>{
  this.sendData()
})

ES6 Features

Template Literals

var name = 'Your name is ' + first + ' ' + last + '.'
var url = 'http://localhost:3000/api/messages/' + id
var name = `Your name is ${first} ${last}.`
var url = `http://localhost:3000/api/messages/${id}`

ES6 Features

Multi-line Strings(Using backticks)

var roadPoem = 'Then took the other, as just as fair,\n\t'
    + 'And having perhaps the better claim\n\t'
    + 'Because it was grassy and wanted wear,\n\t'
    + 'Though as for that the passing there\n\t'
    + 'Had worn them really about the same,\n\t'
var roadPoem = `Then took the other, as just as fair,
    And having perhaps the better claim
    Because it was grassy and wanted wear,
    Though as for that the passing there
    Had worn them really about the same,`

ES6 Features

Classes(OOP)

class Rectangle{
  constructor(height = 0, width = 0) {
    this.height = height;
    this.width = width;
  }
  
  get area() {
    return this.calcArea();
  }

  calcArea() {
    return this.height * this.width;
  }
}

ES6 resources

Why Use TypeScript?

  • Better overall code readability in large codebases
  • Ease of refactoring
  • Use new ES6 features in older browsers
  • IntelliSense auto suggest in code editors

TypeScript

Getting Started

  • Open a Text Editor(Visual Studio Code)
  • Create a file "test-code.js"
  • Write following code
var x = 123;
x.trim();

TypeScript

Getting Started

  • Run "test-code.js" file using node
node test-code.js

a.trim();
  ^

TypeError: a.trim is not a function

Runtime Error

TypeScript

Getting Started

  • Rename "test-code.js" file to "test-code.ts"
  • Run TypeScript compiler
tsc test-code.ts

test-code.ts(2,3): error TS2339: Property 'trim' does not exist on type 'number'.

Compile-time Error

TypeScript

Getting Started

  • Update "test-code.ts" file with following code
var a = ' hello world ';
console.log(a.trim());

TypeScript

Getting Started

  • Run TypeScript Compiler
tsc -watch test-code.ts
  • Open another terminal window
  • Run generated JavaScript file
node test-code.js

TypeScript

Basic Types

TypeScript

Basic Types

// Boolean
let isInProgress: boolean = false;

// Number
let studentsNumber: number = 20;

// String
let name: string = "Luis";

TypeScript

Basic Types

// Template Strings
let name: string = "Luis";
let sentence: string = "Hello, my name is " + name;
let betterSentence: string = `Hello, 
    my name is ${ name }.`

TypeScript

Basic Types

// Array
let arrayA: number[] = [1, 2, 3];
let arrayB: Array<number> = [1, 2, 3];

TypeScript

Basic Types

// Tuple
let x: [string, number];

x = ["hello", 10]; // OK
x = [10, "hello"]; // Error

console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error

TypeScript

Basic Types

// Enum
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
let colorName: string = Color[1];

TypeScript

Basic Types

// Any
let notSure: any = 5;
notSure = "maybe I'm a string";
notSure = false;

TypeScript

Basic Types

// Void
function nothingInteresting(): void {
    let x = 'hello world';
    console.log(x);
}

TypeScript

Basic Types

// Undefined
let undefinedContent: undefined;
undefinedContent = undefined;

// Null
let nullContent: null;
nullContent = null;

TypeScript

Type Assertions

// Angle-bracket syntax
let anyValue: any = 'Welcome to TS';
let anyValueLength: number = 
            (<string>anyValue).length;

// "As" syntax
let anyValue2: any = 'Welcome to TS';
let anyValueLength2 = 
            (anyValue2 as string).length;

TypeScript

Variable Declarations

TypeScript

Variable Declarations

for (var i = 0; i < 10; i++) {
    setTimeout(function() { 
        console.log(i); 
    }, 100 * i);
}
  • Try following code

TypeScript

Variable Declarations

for (var i = 0; i < 10; i++) {
    (function(i){
        setTimeout(function() { 
            console.log(i); 
        }, 100 * i);    
    })(i);
}
  • Using IIFE
    • Immediately Invoked Function Expression

TypeScript

Variable Declarations

for (let i = 0; i < 10 ; i++) {
    setTimeout(function() { 
        console.log(i); 
    }, 100 * i);
}
  • Using "let"

TypeScript

Variable Declarations

function func(allow: boolean) {
    let a = 10;
    if (allow) {
        let b = a + 1;
        return b;
    }

    // Error: 'b' doesn't exist here
    return b;
}
  • Block-scoping/lexical-scoping

TypeScript

Variable Declarations

function foo() {
    // okay to capture 'a'
    return a;
}
// illegal call 'foo' before 'a' is declared
// runtimes should throw an error here
foo();

let a;
  • Capturing a block-scoped variable before it's declared

TypeScript

Variable Declarations

const PI = 3.14;

const myDog = {
    name: 'Rocky',
    age: 2
};

// Error
myDog = {
    name: 'Toby'
    color: 'Black'
}
  • const declarations

TypeScript

Variable Declarations

const myDog = {
    name: 'Rocky',
    age: 2
};

// Allowed
myDog.name = 'Toby';
myDog.color = 'Black';
myDog.name = 'Coco';
  • const declarations

TypeScript

Variable Declarations

let input = [1, 2];
let [first, second] = input;
console.log('first', first); // outputs 1
console.log('second', second); // outputs 2

// This is equivalent to:
let first = input[0];
let second = input[1];
console.log('first', first);
console.log('second', second);
  • Array destructuring

TypeScript

Variable Declarations

// swap variables
[first, second] = [second, first];

// with parameters to a function
function func([first, second]: [number, number]) {
    console.log(first);
    console.log(second);
}
func(input);
  • Array destructuring

TypeScript

Variable Declarations

let [first, ...rest] = [1, 2, 3, 4];
console.log('first', first); // outputs 1
console.log('rest', rest); // outputs [ 2, 3, 4 ]

// Ignore trailing elements
let [first] = [1, 2, 3, 4];
console.log('first', first); // outputs 1
  • Array destructuring(syntax ...)

TypeScript

Interfaces

TypeScript

Interfaces

interface Figura {
    color: string;
    dibujar(): void;
}

interface Linea {
    grosor: number;
}

interface Cuadrado extends Figura, Linea {
    lado: number;
}

TypeScript

Classes

TypeScript

Classes

class Animal {
    nombre: string;

    constructor(nombre: string) {
        this.nombre = nombre;
    }

    mover(distancia: number=0) {
        console.log(`${this.nombre} se movio ${distancia}m.`);
    }
}

TypeScript

Classes

class Gato extends Animal {
    constructor(nombre: string) {
        super(nombre);
    }
    
    mover(distancia: number=1) {
        console.log('Caminando y ronroneando...');
        super.mover(distancia);
    }
}

TypeScript

Classes

class Guepardo extends Animal {
    constructor(nombre: string) {
        super(nombre);
    }
    
    mover(distancia: number=50) {
        console.log('Corriendo para cazar...');
        super.mover(distancia);
    }
}

TypeScript

Classes

let gato: Animal = new Gato('Misifu');
let guepardo: Guepardo = new Guepardo('Corredor');

gato.mover(2);
guepardo.mover();

TypeScript

Access Modifiers

class Animal {
    nombre: string;

    constructor(nombre: string) {
        this.nombre = nombre;
    }

    mover(distancia: number=0) {
        console.log(`${this.nombre} se movio ${distancia}m.`);
    }
}
  • public

TypeScript

Access Modifiers

export class Animal {
    public constructor(public nombre: string) {
    }

    public mover(distancia: number=0) {
        console.log(`${this.nombre} se movio ${distancia}m.`);
    }
}

  • public

TypeScript

Access Modifiers

export class Animal {
    private nombre: string;

    public constructor(nombre: string) {
        this.nombre = nombre;
    }

    public mover(distancia: number = 0) {
        console.log(`${this.nombre} se movio ${distancia}m.`);
    }
}

  • private

TypeScript

Access Modifiers

export class Animal {
    protected nombre: string;

    protected constructor(nombre: string) {
        this.nombre = nombre;
    }

    public mover(distancia: number = 0) {
        console.log(`${this.nombre} se movio ${distancia}m.`);
    }
}

  • protected

TypeScript

Accessors

export class Animal {
    private _nombre: string;

    protected constructor(nombre: string) {
        this._nombre = nombre;
    }

    get nombre(): string {
        return this._nombre;
    }

    set nombre(nombre: string) {
        this._nombre = nombre;
    }

    public mover(distancia: number = 0) {
        console.log(`${this._nombre} se movio ${distancia}m.`);
    }
}

  • get/set

TypeScript

Accessors

export class Animal {
    private _nombre: string;

    protected constructor(nombre: string) {
        this._nombre = nombre;
    }

    get nombre(): string {
        return this._nombre;
    }

    set nombre(nombre: string) {
        if(nombre.length <= 5) {
            console.log('Error. El nombre es muy corto');
            return;
        }

        this._nombre = nombre;
    }

    public mover(distancia: number = 0) {
        console.log(`${this._nombre} se movio ${distancia}m.`);
    }
}

  • get/set

TypeScript

Static Properties

export class Animal {
    static LONGITUD_MINIMA = 5;
    private _nombre: string;

    protected constructor(nombre: string) {
        this._nombre = nombre;
    }

    get nombre(): string {
        return this._nombre;
    }

    set nombre(nombre: string) {
        if(nombre.length <= Animal.LONGITUD_MINIMA) {
            console.log('Error. El nombre es muy corto');
            return;
        }

        this._nombre = nombre;
    }

    public mover(distancia: number = 0) {
        console.log(`${this._nombre} se movio ${distancia}m.`);
    }
}

TypeScript

Abstract Classes

export abstract class Animal {
    static LONGITUD_MINIMA = 5;
    private _nombre: string;

    protected constructor(nombre: string) {
        this._nombre = nombre;
    }

    abstract hacerSonido():void;

    public mover(distancia: number = 0) {
        console.log(`${this._nombre} se movio ${distancia}m.`);
    }

    get nombre(): string {
        return this._nombre;
    }

    set nombre(nombre: string) {
        if(nombre.length <= Animal.LONGITUD_MINIMA) {
            console.log('Error. El nombre es muy corto');
            return;
        }

        this._nombre = nombre;
    }
}

TypeScript

Abstract Classes

import { Animal } from './animal';

export class Gato extends Animal {
    constructor(nombre: string) {
        super(nombre);
    }
    
    mover(distancia: number=1) {
        console.log(`${this.nombre} Esta caminando y ronroneando...`);
        super.mover(distancia);
    }

    hacerSonido(): void {
        console.log(`${this.nombre} dice Miaauuuuu`);
    }
}

TypeScript

Modules

TypeScript

Modules

export {Animal} from "./animal";
export {Gato} from "./gato";
export {Guepardo} from "./guepardo";
  • create "animales.ts" file
  • export classes

TypeScript

Modules

import { Animal, Gato, Guepardo  } from './model/animal/animales';

let gato: Animal = new Gato('Misifu');
let guepardo: Guepardo = new Guepardo('Corredor');
  • create "animales.ts" file
  • import classes

TypeScript

Practice

Practice

Implement following model using TypeScript classes

TypeScript Introduction

By Luis Aviles

TypeScript Introduction

A practical introduction to TypeScript

  • 1,619