Typescript

The Better JavaScript?

Christian Köberl / github.com/derkoe / @derkoe We Are Developers

Christian Köberl

Software Architect / Developer

Develops webapps since 1999

Porsche Informatik
Powering Mobility Business for a Smart World

26 countries, 160 products, 450 employees

More than 1M vehicles sold per year

Datacenter 1500 hosts, 60 TB RAM, 1500 TB disk

Why TypeScript?

 

Code Completion

aka Intellisense Intellisense

Refactoring

Car → Vehicle

 

Backend APIs

   

→ TS

»How I Learned to Stop Worrying & Trust the Compiler«

Felix Rieseberg, TypeScript at Slack

Using Future ECMAScript Features

async/await

Decorators (@)

ES6 Classes

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

let person = new Person(1, 2);
person.mama = 'Mia';
person = Math.sqrt(person);

Types?

 

TypeScript

ES5, ES6/ES2015, TypeScript
  • Statically-typed superset of ES5 and ES2015/16
  • Developed by Anders Hejlsberg / Microsoft 2012

Typescript vs ES6 vs ES5

export class Person {
  private dateOfBirth?: Date;

  constructor(private firstName: string, private lastName: string) {
  }

  toString() {
    return `${this.firstName} ${this.lastName} (${this.dateOfBirth})`;
  }
}

Type Declarations


let a: number;

function toLowerCase(a: string|null) {
  return a ? a.toLowerCase() : null;
}

type AorB = 'A'|'B';
const x: AorB = 'A';

type BiFunc = (a: number, b: number) => number;

Interfaces

interface Person {
  firstName: string;
  lastName: string;
  dateOfBirth?: Date;
}

class Employee implements Person {
  constructor(public firstName: string, public lastName: string) {
  }
}

Type Compatibility

Structural Typing aka Duck Typing
const p = {
  firstName: 'Chris',
  lastName: 'Kö'
};
const person: Person = p;
person.dateOfBirth = new Date();

Type Inference

const name = 'Christian'; // no type needed

// even no types for complex stuff
document
  .getElementById('id')
  .addEventListener('click',
            ev => alert(`${ev.clientX}, ${ev.clientY}`));

Generic Types

class Stack<T> {
    private items: T[] = [];

    public push(item: T) {
        this.items.push(item);
    }

    public pop(): T {
        return this.items.pop();
    }
}

const stack = new Stack<string>();
stack.push("a");
const a = stack.pop(); // a is a string

Integrating JavaScript

Modules and Namespaces

  • Modules correspond to ES6 modules
    export and import
  • Namespaces are translated to IIFEs module pattern

Advanced Topics

Decorators

@Component({a = '1'}) // <<-- decorator
class MyClass {

  @measure // <<-- decorator
  public doSomething() {
    // ...
  }

}
  • Access control, Validation
  • Logging, Profiling
  • Frameworks (e.g. Angular)

Creating Decorators

function measure(target: any, propertyKey: string,
                   descriptor: PropertyDescriptor) {
  const originalFunction = descriptor.value;
  descriptor.value = function (...args: any[]) {
    const start = Date.now();
    originalFunction.apply(target, args);
    console.log(`${propertyKey} with params "${args}"
          took ${Date.now() - start}ms`);
  }
}

async/await

function loadUserName(userId) {
  const url = `https://user-api/user/${userId}`;
  return fetch(url)
    .then(response => response.json())
    .then(user => user.name);
}
async function loadUserName2(userId: string) {
  const url = `https://user-api/user/${userId}`;
  const response = await fetch(url);
  const user = await response.json();
  return user.name;
}
since Typescript 2.3 for target ES5

Similar Tools

Flow is a static type checker for JavaScript.

A transpiler from Java to TypeScript/JavaScript

elm

A delightful language for reliable webapps.

Summary

Static type checking is awesome! (especially with TypeScript)

Use ES2015 and ES.next features!

Thanks! Questions?

github.com/derkoe / @derkoe

PS: We are hiring!

Porsche Informatik logo

Image Credits

  • Title Christian Köberl: © Christian Köberl
  • Rotating arms: Imgur
  • All others © Porsche Informatik

References, Further Readings