TypeScript

http://mbranko.github.io/webkurs

Ovo je deo web kursa

Literatura

Sadržaj

  1. Koncept
  2. Tipovi
  3. Dekoratori
  4. Generički tipovi
  5. Integracija

#1: koncept

ES5 ⊂ ES6/ES2015 ⊂ TypeScript

  • ECMAScript 5 je standardni JavaScript
  • ECMAScript 6, odnosno ECMAScript 2015, je doneo velike novine
  • TypeScript je ES6 + statički tipovi + ono što je planirano za ES7

 

Odstupanje od JavaScripta?

Na zvaničnoj stranici jezika:

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

Trka sa verzijama

  • ono što web čitači podržavaju kasni za podrškom na serveru
  • podrška na serveru kasni za standardom

Trka sa verzijama

  • jednu godinu kasnije...
  • ista situacija, samo novi nivo podrške

Compiler / Transpiler, IDE

  • rešenje: prevođenje koda napisanog u ES6 ili TS u ES5

  • potrebna i podrška u razvojnim alatima
    • MS Visual Studio Code
    • JetBrains WebStorm
    • Eclipse

Šta se htelo popraviti u JavaScriptu?

  • samo dinamički tipovi
  • nema modularnosti
  • preopširni šabloni
    • IIFE: immediately-invoked function expression

  • ukratko: razvoj loše skalira za velike aplikacije

Šta je dobro u JavaScriptu?

  • ima ga svuda
  • ogroman broj biblioteka
  • fleksibilan

Lista želja

  • skalabilan razvoj za HTML5 klijente
  • modularan razvoj
  • lak za učenje za Java i C# programere
  • neinvazivan (postojeće biblioteke i web čitači)
  • dugoročna vizija
  • čist JavaScript izlaz

Karakteristike

  • nadskup JavaScripta
  • tipovi nisu obavezni!
  • prevodi se u ES3 ili ES5
  • nije potrebno posebno runtime okruženje
  • poravnat i sa ES6

  • =>lightweight productivity booster

Početak nije komplikovan


$ npm install -g typescript
$ mv mycode.js mycode.ts
$ tsc mycode.ts
          

Može da otkrije probleme i u postojećem JS!

#2: tipovi

Opcioni tipovi

JavaScript


> var a = 123;
> a.trim()
TypeError: a.trim is not a function
          

run-time

TypeScript


> var a: string = 123;
> a.trim()
Cannot convert 'number' to 'string'
          

compile-time

Tipovi nestaju prilikom izvršavanja

TS compile-time


var a: string = 123;
a.trim()
          

TS run-time


var a = 123;
a.trim()
          

Tipovi

Java TypeScript
Object any
void void
boolean boolean
int, long, ... number
String, char string
Type[] type[]

Tipovi

  • postoji tip funkcija

var find: (elem: string, elems: string[]) => string = 
  function(elem, elems) {
    ...
  }
          

Primer #1: pre uvođenja tipova


var languages = [ { name: "TypeScript", ext: "ts"}, 
                  { name: "JavaScript", ext: "js"},
                  { name: "Java", ext: "java" }]

function findByName(name, elems) {
  var elem;
  elems.forEach(function(index, value) {
    if (value.name.toLower() === name.toLower())
      elem = value;
  })
  return elem;
}
          

Primer #1: posle uvođenja tipova


var languages = [ { name: "TypeScript", ext: "ts"},
                  { name: "JavaScript", ext: "js"},
                  { name: "Java", ext: "java" }]

interface Language {  // <-- duck typing!!! ^^
  name: string
  ext: string
}

function findByName(name: string, elems: Language[]) {
  var elem: Language;
  elems.forEach(function(value, index) {
    if (value.name.toLowerCase() === name.toLowerCase())
      elem = value;
  })
  return elem;
}
          

Primer #2: klase


class Concert {
  artist: String
  price: number
}
          

Primer #2: klase, prošireno


class Concert {
  private static MAX_TICKETS = 500  
  
  constructor(public artist: string, public tickets: number) {
    if(tickets > Concert.MAX_TICKETS) {
      throw new Error("Too many tickets!")
    }
  }
  
  buyTickets(amount: number) {
    if(amount <= this.tickets)
      this.tickets -= amount
    else
      throw new Error("Not enough tickets!")
  }
}
          

Primer #2: klase, nasleđivanje


class RockConcert extends Concert {
  
  constructor(name: string, tickets: number, public volume: number = 11) {
    super(name, tickets)
  }
  
  buyTickets(amount: number) {
    if(amount % 2 === 1)
      throw new Error("Should come in pairs")
    super.buyTickets(amount)
  }
}

var concert = new Concert("Sting", 50)

var rockConcert: Concert = new RockConcert("ACDC", 100)
rockConcert.buyTickets(3)
          

Interfejsi


interface MyInterface {
  // call signature
  (param: number): string

  member: number
  optionalMember?: number

  myMethod(param: string): void
}

var instance: MyInterface = ...
instance(1)
          

Interfejsi

Možemo ih koristiti da opišemo podatke koji se vraćaju iz REST poziva


$.getJSON('user/123').then((user: User) => {
  showProfile(user.details)
})

// User je interfejs
          

Interfejsi su open-ended

Možemo kasnije dodavati u interfejs


interface Point {
    x: number; y: number;
}
declare var myPoint: Point;

interface Point {
    z: number;
}

var myPoint.z; // Dozvoljeno!
          

Enums


enum Language { TypeScript, Java, JavaScript }

var lang = Language.TypeScript
var ts = Language[0]
ts === "TypeScript"
          

enum Language { TypeScript = 1, Java, JavaScript }

var ts = Language[1]
          

Ekspliticna tipizacija

Može biti obavezna:


$ tsc --noImplicitAny mycode.ts
          

TypeScript klase

Kao u Javi:

  • mogu implementirati interfejse
  • nasleđivanje
  • atributi i metode objekta
  • statički atributi i metode

Nije kao u Javi:

  • jedan konstruktor
  • default i opcioni parametri funkcija
  • ES6 sintaksa za klase

Primer #3: modul sa klasama


module StorageModule {
  export interface Storage {
    store(content: string): void
  }

  var privateKey = 'storageKey'
  
  export class LocalStorage implements Storage {
    store(content: string): void {
      localStorage.setItem(privateKey, content);
    }
  }

  export class DevNullStorage implements Storage {
    store(content: string): void { }
  }
}

var storage: StorageModule.Storage = new StorageModule.LocalStorage();
storage.store('testing');
          

Primer #3: JavaScript ekvivalent

var StorageModule;
(function (StorageModule) {
    var privateKey = 'storageKey';

    var LocalStorage = (function () {
        function LocalStorage() {
        }
        LocalStorage.prototype.store = function (content) {
            localStorage.setItem(privateKey, content);
        };
        return LocalStorage;
    })();
    StorageModule.LocalStorage = LocalStorage;

    var DevNullStorage = (function () {
        function DevNullStorage() {
        }
        DevNullStorage.prototype.store = function (content) {
        };
        return DevNullStorage;
    })();
    StorageModule.DevNullStorage = DevNullStorage;
})(StorageModule || (StorageModule = {}));

var storage = new StorageModule.LocalStorage();
storage.store('testing');
          

Strelica-funkcije

  • implicitni return
  • nisu potrebne zagrade za jedan izraz
  • deo ES6


function(arg1) {
  return arg1.toLowerCase()
}
          


(arg1) => arg1.toLowerCase()

          

this je u leksičkom opsegu; ne moramo više pisati
var that = this;

Primer #4: bez strelice


class FatArrow {
  line: HTMLElement = document.createElement("hr")

  constructor() {
    var button = document.createElement("button")
    button.textContent = "Click me!"
    button.addEventListener("click", function(event: MouseEvent) {
      document.body.appendChild(this.line)
      console.log(this)
    })
    document.body.appendChild(button)
  }
}

new FatArrow()
          

Primer #4: sa strelicom


class FatArrow {
  line: HTMLElement = document.createElement("hr")

  constructor() {
    var button = document.createElement("button")
    button.textContent = "Click me!"
    button.addEventListener("click", (event: MouseEvent) => {
      document.body.appendChild(this.line)
      console.log(this)
    })
    document.body.appendChild(button)
  }
}

new FatArrow()
          

#3: dekoratori

Dekorator

  • dekorator je izraz koji se izračunava nakon što je klasa definisana
  • može se koristiti da anotira ili izmeni klasu na neki način

Dekorator


@someDecoratorExpression()
class Car {

  @propertyDecorator() manufacturer: string;

  constructor(@paramDecorator() manufacturer: string) {

  }

  @methodDecorator()
  drive() {

  }
}
          

#4: generički tipovi

#5: integracija sa JS

Integracija sa postojećim JS kodom

  • tip any
  • ambient declarations: opisivanje tipova za postojeći JS kod
  • ekstenzija .d.ts
  • DefinitelyTyped.org: zajednica piše d.ts fajlove za popularne JS biblioteke

DefinitlyTyped.org

  • zajednica piše .d.ts fajlove za popularne JS biblioteke

Moduli su open-ended


// cart.ts
module Webshop {
  export class Cart { ... }
}


// main.ts
module Webshop {
  export class Catalog { ... }
}
          

Moduli su hijerarhijski


module Webshop.Cart.Backend {
  ...
}
          

Kraj dela

← Početak dela

⇐ Početak kursa