Now Hiring!

Graduate and junior developer positions available

JavaScript

var x = "Foo";
x = 3;

TypeScript

Error: Type "Number" is not assignable to type "string"

var x = "Foo";
x = 3;

JavaScript

function square(x) {
  return x * x;
}
console.log(square(3));
console.log(square("foo"));
> 9
> NaN

TypeScript

Error: Type "string" is not assignable to parameter of type "number"

function square(x : number) {
  return x * x;
}
console.log(square(3));
console.log(square("foo"));

Cost of Bugs

Unit Test $100
Integration Test $250
Manual Test $1000
Post-Deployment $16000

Source: https://espincorp.wordpress.com/2014/02/10/ibm-security-appscan-source-edition/

Disclaimer: Data is like 9 years old.

Cost of Bugs

Coding Free? Save $100?
Unit Test $100
Integration Test $250
Manual Test $1000
Post-Deployment $16000

JavaScript

var persons = [
  { firstname: "Fuzzy", surname: "McStickPants" },
  { firstname: "Baloney", surname: "Maloney" }
];

// Someone, a long time ago, in a file far, far away
console.log(
  persons
    .map(function(p) { return p.surname + ", " + p.firstname; })
    .join("; ")
);
> McStickPants, Fuzzy; Maloney, Baloney

Ship It!

3 days later...

"Hey, you should use camel case!"

JavaScript

var persons = [
  { firstName: "Fuzzy", surname: "McStickPants" },
  { firstName: "Baloney", surname: "Maloney" }
];

// Ooops, missed the "firstname" here
console.log(
  persons
    .map(function(p) { return p.surname + ", " + p.firstname; })
    .join("; ")
);
> McStickPants, undefined; Maloney, undefined

TypeScript

interface Person {
  firstname : string,
  surname : string
};

var persons : Person[] = [
  { firstname: "Fuzzy", surname: "McStickPants" },
  { firstname: "Baloney", surname: "Maloney" }
];

// Someone, a long time ago, in a file far, far away
console.log(
  persons.map(p => p.surname + ", " + p.firstname).join("; ")
);
> McStickPants, Fuzzy; Maloney, Baloney

Ship It!

3 days later...

"Hey, you should use camel case!"

TypeScript

interface Person {
  firstName : string,
  surname : string
};

var persons : Person[] = [
  { firstName: "Fuzzy", surname: "McStickPants" },
  { firstName: "Baloney", surname: "Maloney" }
];

// Ooops, missed the "firstname" here
console.log(
  persons.map(p => p.surname + ", " + p.firstname).join("; ");
);

Error: "firstname" does not exist on interface "Person"

TypeScript

interface Person {
  firstName : string,
  surName : string
};

var persons : Person[] = [
  { firstName: "Fuzzy", surname: "McStickPants" },
  { firstName: "Baloney", surname: "Maloney" }
];

// Fix'd
console.log(
  persons.map(p => p.surname + ", " + p.firstName).join("; ")
);
> McStickPants, Fuzzy; Maloney, Baloney

What Else?

The Run Down

JavaScript

TypeScript

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        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);
var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function () {
    alert(greeter.greet());
};
document.body.appendChild(button);

Damn close to JavaScript

Chasing the ES6 Standard

Arrow Functions

// JS
["a", "bb", "ccc"]
  .map(function(s) { return s.length; })
  .reduce(function(a, b) { return a + b; });

// TS
["a", "bb", "ccc"]
  .map(s => s.length)
  .reduce((a, b) => a + b );

Captured "this" context

class Foo {
  multiplier : number = 3

  multiply(inputs : number[]) {
    return inputs.map(n => n * this.multiplier);
  }
}

// compiles to
    Foo.prototype.multiply = function (inputs) {
        var _this = this;
        return inputs.map(function (n) { return n * _this.multiplier; });
    };

Object Oriented

interface Foo {
  bar() : void
}

abstract class Bar implements Foo {
  private x : number = 3;

  public bar() : void {
    this.x *= this.getMultiplier();
  }

  protected abstract getMultiplier() : number;
}

class TwoBar extends Bar {
  protected getMultiplier() : number { 
    return 2;
  }
}

Constructor Binding

public class PersonController {
  constructor(private personRepository : IPersonRepository) {
  }
  
  get people() : Person[] {
    return this.personRepository.all;
  }
}

Generics

interface IRepository<T> {
  all : T[]
}

public class PersonController {
  constructor(this personRepository : IRepository<Person>) {
  }
  
  get people() {
    return this.personRepository.all;
  }
}

Type Inference

interface Identifiable {
  id : string
}
class Person {
  constructor(public id : string) {
  }
  
  walkSomewhere() {	  
  }
}

var x : Identifiable = new Person("Foo"); // Works
var y : Identifiable = { id: "Foo" }; // Works
var z : Person = y; // Doesn't work

Type Compatibility

class Point {
    constructor(public x : number, public y : number) {
    }
}
class Vector {
    constructor(public x : number, public y : number) {
    }

    get length() { 
      return Math.sqrt(this.x*this.x + this.y * this.y);
    }
}

var point = new Point(1, 2);
var vector = new Vector(3, 4);

point = vector; // Works
vector = point; // Does not work, missing 'length'

Declaration Merging

interface Foo {
  field1 : string
}

interface Foo {
  field2 : string
}

// Both fields required
var x : Foo = {
  field1: "Hi",
  field2: "Mum"
}

Modules

import { IObservable<T> } from "Rx";

function watchEvents(events : IObservable<Event>) {
  events.subscribe(e => console.log(e) );
}
  • ES6 Syntax (other syntaxes are legacy)
  • Compiles to AMD, CommonJS, UMD and System

Type Definitions

// d3.d.ts

declare module d3 {
  export function select(selector: string): Selection<any>;

  interface Selection<Datum> {
     // ...etc
  }

  // ...etc
}
npm install -g tsd
tsd install d3 --save

IDE Support

  • Visual Studio 
  • VS Code
  • WebStorm
  • Sublime
  • I imagine others...

Show me codes!

BrisTS

By xwipeoutx

BrisTS

  • 1,436