Typescript

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
Any browser. Any host. Any OS. Open Source.

Plan

  • All the history about TS in details
  • Biography of the creator
  • A small code example to finish off.

Real PLAN

  • I will tell you about TS in general
  • A little about ES2015
  • I will try to answer the question "Why TS?"
  • Pros and Cons
  • Type system
  • Some runtime TS features
  • Transpiled output
  • How to start using TS in your project
  • typescript@next

Overview

in general

HISTORY

  • Developed And Maintained By Microsoft (I know, I know..)
  • Introduced in October 2012 by Ander’s Hejlsberg
  • First public appearance: October 1, 2012

Anders Hejlsberg, lead architect of C# and creator of Delphi and
Turbo Pascal, has been working on the development of
TypeScript

BACKSTORY

  • Free & Open source language
  • It is a “superset of JavaScript”
  • Influenced By Javascript, Java, And C#
  • Conforms to ECMA standards & proposals
  • Rapidly becoming an Industry Standard (Angular 2)
  • Build Plugins for maven, gradle, grunt, gulp, webpack

Any browser

I'm on the edge!

COMPATIBILITY

Any OS

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

COMPATIBILITY

ES5

ES2015

ES2016

TS

ES+

What is superset

COMPILE-TO-JS LANGUAGES

Good old standards...

What do we have?

  • Dart
  • elm
  • ​CoffeeScript
  • PureScript
  • ​TypeScript
  • ...

WHO is USING TYPESCRIPT

ES2015

AKA ES6

May '95

Dec '95

Sep '95

1997

Aug '96

1999

1998

2009

2003

2015

2011

2016

Mocha  (Brendan Eich, Netscape)

LiveScript

JavaScript

Edition 1

JScript  (Microsoft)

Edition 2

Edition 3

Edition 4

Edition 5

Edition 5.1

Edition 6

Edition 7

ECMA-262 specification

  • Latest finalised version ECMAScript 2015
  • Change to yearly naming convention (ES7 = ES2016)

History

WHAT IS Es2015?

  • ECMAScript 2015, also known as ECMAScript 6  is the upcoming version of the ECMAScript standard.
  • This standard is ratificationed in June 2015.
  • ES6 is a significant update to the language, and the first update to the language since ES5 was standardized in 2009.

CLASS

ES6 classes are 'syntactic sugar' on top of prototypal inheritance

class Client {

    constructor(firstname, lastname) {
        this.id = undefined
        this.firstname = firstname
        this.lastname = lastname
    }

    getFullName() {
        return this.firstname + this.lastname
    }

    generateId() {
        this.id = generateGuid()
    }

}

STATIC METHODS

class Client {

    constructor(firstname, lastname) {
        this.id = undefined
        this.firstname = firstname
        this.lastname = lastname
    }

    getFullName() {
        return this.firstname + this.lastname
    }

    generateId() {
        this.id = generateGuid()
    }

    static generateGuid() {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
            .toString(16)
            .substring(1)
        }
        
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
        s4() + '-' + s4() + s4() + s4()
    }
    
}
  • Can't be called on an instantiated class
  • No access to 'this' properties/methods
  • Most useful when associated with class, but don't need unique variables of instanced class

 

ES6 introduces the 'extend' keyword

class TCSClient extends Client {

    this.evalSystem = "TCS"

}

ES6

class TCSClient extends Client {

    getFullName() {
        return this.firstname + " " +
            this.lastname
    }

}

ES6

Can override functions by re-implementing them in child class

INHERITANCE

MODULES

class ClientService {
    
    clients = [];

    addClient(client) {
        this.clients.add(client);
    }

}

export ClientService;
import {ClientService} from './ClientService';

class ClientComponent {

    submitClient(client) {

        ClientService.addClient(client);

    }

}

In ES6 each module is defined in its own file. The functions or variables defined in a module are not visible outside unless you explicitly export them.

main.js

ClientService.js

LET

  • Alternatives to declaring a variable with 'var'
  • 'let' block-scopes variables rather than var's function- scoping
var x = 1;
if (x) {
    let x = 2;
}
console.log(x);
> 1

ES6

Console

  • Using 'let' allows for block-scoping ( {} )
  • Maintains encapsulation principles
  • Allows same variable names where appropriate
const stuff = { things: ['chair', 'desk', 'computer'] };

const stuff = { things: ['chair', 'desk', 'computer'] };
stuff = {}; // fails
console.log(stuff.things); // ...

const stuff = { things: ['chair', 'desk', 'computer'] };
stuff.things.push('pot plant');
console.log(stuff.things);
// chair,desk,computer,pot plant
  • Also block-scoped
  • Must be decalred using an initializer
  • Can only be assigned to once 
  • Will fail silently if assigned again
  • Does not make the assigned value itself immutable

CONST

ARROW FUNCTIONS

  • Also known as lambda expressions
  • Makes code more 'terse'
var arrow = function() {}
var arrow = () => {}

becomes

function() {}
() => {}

becomes

  • 'return' keyword implied for single expressions in function body
  • No parentheses required for 1 argument
function(a) { return a * a }
a => a * a

becomes

  • Parentheses for 0, or >1 arguments
function(a, b) { return a + b }
(a, b) => a + b

becomes

  • A 'fat arrow' takes the place of the 'function' keyword

ARROW FUNCTIONS

function Counter() {
    this.seconds = 0;
    setInterval(function() {
        this.seconds++
    }.bind(this), 1000);
}
function Counter() {
    this.seconds = 0;
    setInterval(() => this.seconds++, 1000);
}
  • Arrow functions are bound to their lexical scope
  • 'this' in an arrow function is the same as the outer scope
  • Best used for functions with low amount of arguments/statements

ES5

ES6

ARROW FUNCTIONS

var text = `
    This is a template literal
    'It can span multiple lines'
    "And can contain quotation marks"
    `
var text = (
    'This is the old method\n' +
    'for strings spanning\n' +
    'several lines'
)

var text = [
    'Or',
    'perhaps',
    'this'
].join('\n')
    
  • A string wrapped in backticks ( ` )
  • Can be multiline
  • Strings can contain ' and " characters without escaping

ES5

ES6

TEMPLATE LITERALS

var text = `the time and date is ${new Date().toLocaleString()}`

var a = 6;
console.log(`The number is ${a}`)

Can interpolate expressions with ${expression}

TEMPLATE LITERALS

let myObject = { foo:'bar', baz: 'qux' };
//....
let { foo, baz } = myObject

console.log(foo) // 'bar'

console.log(baz) // 'qux'

An object literal lets us create multiple properties at the same time

An object pattern lets us extract multiple properties at the same time

Properties mapped to aliases

ASSIGNMENT DESTRUCTURING

function swapIf () {
    var left = 10;
    var right = 20;
    var aux;
    
    if(right > left) {
        aux = right;
        right = left;
        left = aux;
    }
}
function swapIf () {

    var left = 10
    var right = 20    
    
    if(right > left) {
        [left, right] = [right, left]
    }
}

Can swap variables without need for a temporary variable

ES5

ES6

ASSIGNMENT DESTRUCTURING

function displayNameAge ( {name, age} ) {
    console.log(`${name} is ${age} years old`)
}

displayNameAge( { age: 27, name: 'John'} ) // 'John is 27 years old'

Can destructure a function's parameter list

ASSIGNMENT DESTRUCTURING

function getCoordinates() {
    return {
        x: 5,
        y: 22
    }
}

var {x, y} = getCoords()

console.log(x) // 5
console.log(y) // 22
function getCoordinates() {
    return {
        x: 5,
        y: 22
    }
}

var object = getCoordinates();
var x = object.x;
var y = object.y;

console.log(x) // 5
console.log(y) // 22

Possible use cases

More terse interaction with returned objects

ES5

ES6

ASSIGNMENT DESTRUCTURING

WHY TYPESCRIPT?

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

Dynamic

TYPING....

Static

JavaScript, Python,
Ruby, PHP

C, C++, C#, Java, Fortran, Haskell 

  var number = 5;
  number = "Hello!";
  //👍np, bro!
  int a = 10;
  a = "Hello!"; 
  //🔥Compiler Error 

JAVASCRIPT


  function numberCruncher (numA, numB){
    return numA + numB;
  }
var result = numberCruncher(5, 5);
console.log(result); 
>> 10
result = numberCruncher(5, true);
console.log(result); 
>> 6 😒
result = numberCruncher(5, 'js4lyfe');
console.log(result); 
>> "5js4lyfe" 😁
result = numberCruncher(5, {param: true});
console.log(result); 
>> "5[object Object]" 👀🔫

TYPING WITH TYPESCRIPT

  function myTypedFunction(paramName : dataType) : returnType {
    // Regular junk here
  }
  var varName : string = 'Yeah baby!';

Type a variable:

Type a function:

  function trimLength(inputVal : string) : number {
    return inputVal.trim().length;
  }

Available Types:
Standard JS Types: Boolean, Number, String, Array
Also includes Enum, Any, Void

A function that returns nothing

VOID


  function initSomething() : void {
    doSomeStuff();
  }
var pointless = initSomething(); // 🍋Compiler Error

ANY

Restores basic JavaScript dynamic typing behavior


  var foo : any;

  declare var jQuery : any;

  jQuery.get('/awesome.html');
foo = 'Hello!';
foo = true;
foo = 42;

Proof

export interface UserPositionInfo {
    jobFunctionId?: number;
    title?: string;
    level: number;
}

export interface SidebarItem {
    name?: string;
    iconUrl?: string;
    applicationUrl?: string;
}

export interface AppContextVM {
    userId: number;
    userName?: string;
    isDev: boolean;
    currentPosition?: UserPositionInfo;
    sidebarItems?: SidebarItem[];
}

JAVA TYPES

CRAZY OOP DIAGRAMS

People thoughts

AREN'T WE ALREADY USING TYPES?

WHY TYPESCRIPT?

  • Provide an optional type system for JavaScript
  • Provide planned features from future JavaScript editions to current JavaScript engines
  • Types increase the agility when doing refactoring
  • Types are one of the best forms of documentation you can have.

TYPESCRIPT is JAVASCRIPT

  • TypeScript is a superset of JavaScript
  • TypeScript provides compile time type safety for JavaScript code
  • Types in TypeScript are completely optional
  • .js file can be renamed to .ts file and TypeScript will still compile to .js equivalent to the original*

WHY USE TYPESCRIPT?

  • It's JavaScript, but better...with intellisense and API help
  • Smaller Transpiled output than ES2015's
  • Help's Identify Bugs during design... instead of after deployment
  • Easy to configure
  • Better overall code readability in large codebases
  • Ease of refactoring
  • IntelliSense auto suggest in code editors

DESIGN TIME ANALYSIS

  • Finding bugs earlier in your development process
  • Fix a bug in your logic at design time rather than fixing the bug at run time.
  • Runtime bugs can slip under a crack in your logic and lurk there (sometimes for months) until discovered.

TypeScript IS JAVASCRIPT AT SCALE

  • Checks code on the fly at design time
    • Compatible with most editors, via plugins to:
      • Provides custom code completion
      • Error identification via tooltips (with plugin support)
    • Allows you to catch bugs prior to JS build
  • Transpiles to ES5
    • tsc watcher for compiling on save
    • ES5 output is ~HALF the size of Babel’s

Pros and Cons

of using typescript

Benefits

  • Static analysis
    • You'll always know how the object works
    • The IDE will also help (autocomplete)
    • Nobody will add arbitrary variables
  • ES Compatibility
  • Matured technology
  • Well supported
  • 'JavaScript safe'

pros and cons

Static typing

Cons

Pros

  • Documentation
  • IDE support
  • Detection of mistakes
  • More verbose
  • d.ts
  • Delay in developing high-end features (like JSX)

IT'S ES2015!

  • Arrow Functions
  • Spread
  • Block scoping (let & const)
  • Classes with constructors, get/set
  • Enhanced Object Literals
  • Template Strings
  • Destructuring
  • Iterables and Iterators

Plus

  • Types
  • Decorators (from ES7)
  • Generics
  • Enums!
  • Class Extensions
  • ​Access Modifiers
  • Interfaces
  • Namespaces

TYPE ANNOTATIONS

FUNCTION PARAMETERS


/**
 * @param {string} msg Message to display.
 */
function Display(msg) {
    console.log(msg);
}

/**
 * @param {boolean} [loud=false] Greet "loudly".
 */
function Greet(loud) {
    if (typeof loud === 'undefined') {
      loud = false;
    }
    var msg = "Hello World";
    console.log(loud ? msg.toUpperCase() : msg);
}

/**
 * @param msg Message to display.
 */
function Display(msg: string) {
    console.log(msg);
}

/**
 * @param loud Greet "loudly".
 */
function Greet(loud: boolean = false) {
    var msg = "Hello World";
    console.log(loud ? msg.toUpperCase() : msg);
}




function Display(msg) {
    console.log(msg);
}




function Greet(loud) {
    if (typeof loud === 'undefined') {
      loud = false;
    }
    var msg = "Hello World";
    console.log(loud ? msg.toUpperCase() : msg);
}

CLASS PROPERTIES






class Person {

    name: string;
    age:  number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age  = age;
    }

}
/**
 * @class Person
 * @param {string} name
 * @param {number} age
 */
function Person(name, age) {

  /**
   * @name Person#name
   * @type string
   */
  this.name = name;

  /**
   * @name Person#age
   * @type number
   */
  this.age = age;
}





function Person(name, age) {
  this.name = name;
  this.age  = age;
}

INCORRECT USAGE


var person = new Person("Dima", 23);

person.talks()

RUNTIME ERROR

Uncaught TypeError: undefined is not a function

COMPILER ERROR

Property 'talks' does not exist on type 'Person'.

We're Not Writing C

It's not about telling the computer how to store data, it's about validating your assumptions.

Types

Class, inheritance, interface, generic, type inering

TYPESCRIPT TYPES

var num: number = 123;
function identity(num: number): number {
  return num;
}
identity('string'); // error!


var myNumbers : number[] = [170, 2.6, 2245, 3032, 400];

Void type represents the absence of a value and is used similar to null and undefined

Void TYPE

var n: number = null;   // Primitives can be null
var x = null;           // Same as x: any = null
var x: void = null;     // Correct
x = 2;                  // Error
var e: Null;            // Error, can't reference Null type

VOID & ANY

function initSomething() : void {
    doSomeStuff();
}

var pointless = initSomething(); // Compiler Error
// if you absolutely have to (don't do it young Jedi!)
var foo : any;
foo = 'Hello!';
foo = true;
foo = 42;

Functions

  • In TypeScript every parameter to a function is assumed to be required by the function.

  • The number of parameters to the function has to match with the number of parameters the function expects.

REQUIRED PARAMETERS

function fullName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}

var result1 = fullName("Bob");  //error, too few parameters
var result2 = fullName("Bob", "Adams", "Sr.");  //error, too many parameters
var result3 = fullName("Bob", "Adams");  //ah, just right
  • In JavaScript, every parameter is considered option and assumed to be undefined.

  • Using the '?' to denote option parameters in TypeScript

OPTIONAL PARAMETERS

function fullName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

var result1 = fullName("Bob");  //works correctly now
var result2 = fullName("Bob", "Adams", "Sr.");  //error, too many parameters
var result3 = fullName("Bob", "Adams");  //ah, just right

OPTIONAL PARAMETERS

buildName(firstName: string, lastName?: string {
  if (lastName) {
    return firstName + ' ' + lastName;
  } else {
    return firstName;
  }
}

let result1 = buildName('Steve');                   // 'Steve'
let result2 = buildName('Steve', 'Hartzog');        // 'Steve Hartzog'

// Compiler error, too many parameters
let result3 = buildName('Steve', 'Hartzog', 'Jr.'); 

We can also set up a value that an optional parameter will have if the user does not provide one.

 DEFAULT PARAMETERS

function fullName(firstName: string, lastName = "Smith") {
    return firstName + " " + lastName;
}

var result1 = fullName("Bob");  //works correctly now, also
var result2 = fullName("Bob", "Adams", "Sr.");  //error, too many parameters
var result3 = fullName("Bob", "Adams");  //ah, just right
  • Use to group multiple parameters into one.

  • Similar to argument in JavaScript

 REST PARAMETERS

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

var employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

CLASSES

Very similar to classes in C# or Java

CLASS MODEL

class Point {
    x: number;
    y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    add(point: Point) {
        return new Point(this.x + point.x, this.y + point.y);
    }
}
class Person {

    constructor(name) {
        this.name = name;
    }

    greet() {
        return 'My name is ' + this.name;
    }
}

var annabelle = new Person('Annabelle');

console.log(annabelle.greet());
// > My name is Annabelle
class Person {

    constructor(public name: string) { }

    greet(): string {
        return 'My name is ' + this.name;
    }

}

var annabelle = new Person('Annabelle');

console.log(annabelle.greet());
// > My name is Annabelle

ES6

TypeScript

Class

Classes in TypeScript support single inheritance using the extends keyword

INHERITANCE

class Point3D extends Point {
    z: number;

    constructor(x: number, y: number, z: number) {
        super(x, y);
        this.z = z;
    }

    add(point: Point3D) {
        var point2D = super.add(point);
        return new Point3D(point2D.x, point2D.y, this.z + point.z);
    }
}

ACCESS MODIFIERS

class FooBase {
    public x: number;
    private y: number;
    protected z: number;
}

// EFFECT ON INSTANCES
var foo = new FooBase();
foo.x; // okay
foo.y; // ERROR : private
foo.z; // ERROR : protected
  • public: available everywhere on instances
  • private: not available for access outside the class
  • protected: available on child classes but no on instances directly
class FooChild extends FooBase {
    constructor(){
      super();
        this.x; // okay
        this.y; // ERROR: private
        this.z; // okay
    }
}

INTERFACE

can be substituted for another interface type or object type literal with an identical set of members.

INTERFACE AS TYPE

interface IPlant{
    name: string;
    genus: string;
    category: string;    
}
var plant: IPlant;
plant = new Plant();
class Plant{
    name: string;
    genus: string;
    category: string;	
}

Interface can be used to constrain a set of classes to implement the same set of properties or functions.

INTERFACE AS TYPE

class tree implements IPlant {
    name: string;
    genus: string;
    category: string;	
}
// TypeScript would produce an error 
// because the "flowers" class does not
// implement a "genus" category
class flowers implements IPlant {
    name: string;
    category: string;	
}
interface IPlant{
    name: string;
    genus: string;
    category: string;    
}

GENERICS

that will accept any and all types for the type of 'arg'. However, we lose the information about what type was when the function returns

'ANY' KEYWORD

function identity(arg: any) {
    return arg;
}

var output1 = identity('hello') // output is string
var output2 = identity(123) // output is number

This 'T' allows us to capture the type the user provides, so we know the return type of the function.

'T' GENERIC TYPE

function identity<T>(arg: T): T {
    return arg;
}

var output1 = identity<string>('hello') // type of output is string
var output2 = identity(123) // type of output is number
var output3 = identity<boolean>(true) // type of output is boolean

Generic Constraints

Here, we’ll create an interface that has a single .length property and then we’ll use this interface and the extends keyword to denote our constraint:

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length); 
    return arg;
}

 Union Types 

Occasionally, you’ll run into a library that expects a parameter to be either a number or a string. For instance, take the following function:


function padLeft(value: string, padding: string | number) {
    // ...
}

// errors during compilation
let indentedString = padLeft("Hello world", true); 

Intersection Types

type LinkedList<T> = T & { next: LinkedList<T> };

interface Person {
    name: string;
}

var people: LinkedList<Person>;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;

Intersection types are closely related to union types, but they are used very differently.

String Literal Types

type Easing = "ease-in" | "ease-out" | "ease-in-out";
class UIElement {
    animate(dx: number, dy: number, easing: Easing) {
        if (easing === "ease-in") {
            // ...
        }
        else if (easing === "ease-out") {
        }
        else if (easing === "ease-in-out") {
        }
        else {
            // error! should not pass null or undefined.
        }
    }
}

let button = new UIElement();
button.animate(0, 0, "ease-in");
button.animate(0, 0, "uneasy"); // error: "uneasy" is not allowed here

String literal types allow you to specify the exact value a string must have.

declaration file 

When using an external JavaScript library, or new host API, you'll need to use a declaration file (.d.ts) to describe the shape of that library.

declare class Tether {
    constructor(options: Tether.ITetherOptions);
    public setOptions(options: Tether.ITetherOptions): void;
    public enable(): void;
    public static position(): void;
}

declare namespace Tether {
    interface ITetherOptions {
        classes?: {[className: string]: boolean};
        classPrefix?: string;
        constraints?: ITetherConstraint[];
        element?: HTMLElement | string | any /* JQuery */;
    }

    interface ITetherConstraint {
        attachment?: string;
        pin?: boolean | string[];
        to?: string | HTMLElement | number[];
    }
}

declare module "tether" {
    export = Tether;
}

type inference

In TypeScript, there are several places where type inference is used to provide type information when there is no explicit type annotation. For example, in this code

let x = 3; // The type of the x variable is inferred to be number.

function createZoo(): Animal[] {
    return [new Rhino(), new Elephant(), new Snake()];
}

let zoo = createZoo(); // It is Animal[]

function echo<T>(value: T) {
  return value;
}

let numb = echo<number>(2); // numb is number
let text = echo('Some'); // text is string

SHOULD WE LOVE

Why should we love TypeScript?

  • Code Completion
  • Find Occurrences
  • Refactoring
  • List Parameters
  • Go To Definition
  • Inline Errors

MOST PRE-EXISTING JAVASCRIPT
IS ALREADY VALID TYPESCRIPT

  var items = getItems();
  var goSportsTeam = true;
  var letter = 'z';

some-javascript.js

some-typescript.ts

Static Types

ECMAScript 6

...and more!

What does it give us?

Runtime features

Enum, namespace

ENUMS

enum CardSuit {
  Clubs,
  Diamonds,
  Hearts,
  Spades
}

// Sample usage
var card = CardSuit.Clubs;

switch (myCard.suit) {
  case CardSuit.Clubs:
    console.log(CardSuit.Clubs);
    break;
  otherwise:
    console.log('Not a club.');
}

NAMESPACES

  • aka Internal Modules
  • Reduce global footprint
  • Open to be extended
  • No Helper libraries required
namespace my.example {
	
	export function doSmth(){
		// Actions
	}
	
}

// Somewhere else
console.log(my.example.doSmth())

Output

TYPESCRIPT TRANSPILATION

TRANSPILATION

  • No type checking required in our code
  • No type checking added into the output
// ES2015
doSomething (smidge) {
  if (smidge instanceOf repo
    && smidge.myProp) {
    let a = smidge.myProp;
  }
  //...
}
// Transpiled ES5
function doSomething (smidge) {
  if (smidge instanceOf repo
    && smidge.myProp) {
    var a = smidge.myProp;
  }
  //...
}
// TypeScript
doSomething (smidge:repo) {
  let a = smidge.myProp;
  ...
}
// Transpiled ES5
function doSomething (smidge) {
  var a = smidge.myProp;
  ...
}

GETTERS/SETTERS

JAVASCRIPT

function Troll() {}

Object.defineProperty(Troll.prototype, "message", {

    get: function () {
        return "You mad bro?";
    },

    set: function (msg) {
        console.log("Cool message bro ...");
    }
    
});

TYPESCRIPT

class Troll {

    get message() {
        return "You mad bro?";
    }

    set message(msg) {
        console.log("Cool message bro ...");
    }

}

TRANSPILED

var Troll = (function () {
    function Troll() {
    }
    Object.defineProperty(Troll.prototype, "message", {
        get: function () {
            return "You mad bro?";
        },
        set: function (msg) {
            console.log("Cool message bro ...");
        },
        enumerable: true,
        configurable: true
    });
    return Troll;
})();

FUNCTIONS

JAVASCRIPT


function DoSomethingCool() {
    // no ...
}

TYPESCRIPT


function DoSomethingCool() {
    // no ...
}

TRANSPILED


function DoSomethingCool() {
    // no ...
}

ARROW FUNCTIONS

JAVASCRIPT


function Fetcher () {};

Fetcher.prototype.massageIt = function (data) {
    return data;
};

Fetcher.prototype.fetchStuff = function () {
    var _this = this;
    return getJSON("/stuff").then(function (data) {
        return _this.massageIt(data.data);
    });
};

TYPESCRIPT


function Fetcher () {}

Fetcher.prototype.massageIt = function (data) {
    return data;
};

Fetcher.prototype.fetchStuff = function () {
    return getJSON("/stuff").then((data) => {
        return this.massageIt(data.data);
    });
};

TRANSPILED

function Fetcher() {
}
Fetcher.prototype.massageIt = function (data) {
    return data;
};
Fetcher.prototype.fetchStuff = function () {
    var _this = this;
    return getJSON("/stuff").then(function (data) {
        return _this.massageIt(data.data);
    });
};

DEFAULT PARAMETERS

JAVASCRIPT


function Say(words) {
    if (typeof words === 'undefined') {
        words = "Hello World";
    }
    console.log(words);
}

TYPESCRIPT


function Say(words = "Hello World") {
    console.log(words);
}

TRANSPILED


function Say(words) {
    if (words === void 0) { words = "Hello World"; }
    console.log(words);
}

REST PARAMETERS

JAVASCRIPT


function Add(/* ...values */) {
    var slice  = Array.prototype.slice,
        values = slice.call(arguments);
    return values.reduce(function (sum, value) {
        return sum + value;
    });
}

TYPESCRIPT


function Add(...values) {
    return values.reduce((sum, value) => sum + value);
}

TRANSPILED


function Add() {
    var values = [];

    for (var _i = 0; _i < arguments.length; _i++) {
        values[_i - 0] = arguments[_i];
    }

    return values.reduce(function (sum, value) {
        return sum + value;
    });
}

TEMPLATE STRINGS

JAVASCRIPT


var name = "Dima",
    age  = 23;

console.log("My name is " + name + ". I'm " + 
    age + " years old")

TYPESCRIPT


var name = "Dima";
var age  = 23;
var isFree = true;

console.log(`My name is ${name}. I'm ${age} years old 
    and I'm ${isFree ? '' : 'not'} free`);

TRANSPILED

var name = "Dima";
var age = 23;
var isFree = true;
console.log("My name is " + name + ". I'm " + age 
    + " years old \n    and I'm " 
    + (isFree ? '' : 'not') + " free");

MODULES

JAVASCRIPT


var MyModule = MyModule || {};

MyModule.Foo = "Bar";

MyModule.LogFoo = function () {
    console.log(MyModule.Foo);
};

TYPESCRIPT

namespace my.example {
	
	export function doSmth(){
		// Actions
	}
	
}

TRANSPILED

var my;
(function (my) {
    var example;
    (function (example) {
        function doSmth() {
            // Actions
        }
        example.doSmth = doSmth;
    })(example = my.example || (my.example = {}));
})(my || (my = {}));
// Somewhere else
console.log(my.example.doSmth());

How to start using TS in your project?

without sms and registration

TODO

  1. Start using ES2015 modules
  2. Install TypeScript
  3. Configure TypeScript
  4. Add TypeScript support to your IDE
  5. Add typings to the libs in your project
  6. Set up building system like webpack
  7. Configure webpack

Install TypeScript

The command-line TypeScript compiler can be installed as a Node.js package.

# INSTALL
npm install -g typescript

#COMPILE
tsc helloworld.ts

EASY TO CONFIGURE

tsconfig.json

{
  "compilerOptions": {
    "jsx": "react",
    "module": "commonjs",
    "noEmitOnError": true,
    "outDir": "./dist/",
    "removeComments": true,
    "allowJs": true
  },
  "files": [
    "./index.ts" // Entry point
  ]
}

TypeScript Editor Support

alm.tools
Atom
Eclipse
Emacs
NetBeans
Sublime Text
Vim
Visual Studio
Visual Studio Code
WebStorm

Typings 

The TypeScript Definition Manager

# Install Typings CLI utility.
npm install typings --global

# Install i.e. React.js
typings install --save --ambient react

# If you use the package as a module:
# Install non-ambient typings 
typings install chai --save

# If you use the package through script tag, or
# it is part of the environment, or
# the non-ambient typings is not yet available:
# Install ambient typings 
typings install mocha --ambient --save

Webpack

...
module: {
    loaders: [{
            test: /\.tsx?$/,
            loader: 'awesome-typescript',
            include: [path.resolve(path.join(__dirname, "src"))],
            query: {
                doTypeCheck: true,
                useCache: true,
                forkChecker: true,
                usePrecompiledFiles: true,
                tsconfig: './src/tsconfig.json',
                cacheDirectory: __dirname + '/.awcache'
            }
        }]
}
...

DOC GENERATOR

typescrpt@next

What future versions wil include

V 2.0

  • Non-nullable types
  • Control flow based type analysis
  • Readonly properties 
  • Use path mappings in module resolution
  • Support private and protected constructors
  • Support abstract properties
  • Support for UMD module definitions
  • async/await and generators support for ES5/ES3
  • Type guards on property access
  • Glob support in tsconfig.json
  • Decorators for function expressions/arrow functions
  • ...

V 2.1

  • Support ES8 object property spread and rest
  • Variadic types
  • Deprecated decorator
  • Support for project references
  • ...

SUMMARY

  • As open as JavaScript.
  • It IS ES2015, plus some features.
  • Smaller, simpler output than babel.
  • Advantages at scale.
    • Helps catch bugs at design time.
    • Custom Code Completion.
  • Easy to integrate into existing build.
  • Plugins for all dev environments.
  • Simple to convert.

CONCLUSION

Matured technology

Well supported

'JavaScript safe'

Must have in every project

One more thing!

A little story

about react.js, modules and migrations

aT THE BEGINING...

  • No direct imports, just use as is
  • No webpack, gulp, npm and other stuff
  • .NET build everything: JS, TS, CSS...

Preparation

We decided to move to main-stream front-end Technologies

  1. First we needed to start use modules
    • Common.js - only relative require
    • AMD - not so popular
  2. Builder
    • Gulp - just plain task runner
    • webpack - Module shim 
  3. LESS and Typescript compiler
    1. less-loader for LESS
    2. awesome-typescript-loader for TypeScript
  4. Start using NPM as most as possible

Problems

  • Architecture - how to organise folders
  • Module injections
  • Case sensivity
  • Build speed
  • Integration to Visual Studio
  • Circule dependencies

File organising

Module injections

Case sensivity

Build speed

Circule dependencies

Useful links

THANKS FOR YOUR ATTENTION

Typescript

TypeScript

By Dima Pikulin

TypeScript

JavaScript that scales

  • 1,541