Types vs Types

@ilavriv

Preferences of types

  • Abstraction (or modularity)
  • Documentation
  • Optimization
  • Safety

Types in JavaScript ecosystem

  • JSX
  • Flow 
  • TypeScript 
  • Elm

JSX

 

Optimized JavasScript 

 

npm: 

https://npmjs.org/package/jsx

 

Flow

 

Static types checker

 

npm: 

https://www.npmjs.com/package/flow

site: 

https://flowtype.org

 

TypeScript

 

Types Definition

 
// JSX: 

class _Main {
    static function main(args: string[]) : void {
        log args;
    }
}
// Flow: 


function main(args: Array<string>) {
    console.log(`args: ${args}`);
}
// TypeScript: 


class Main {
    constructor(args: Array<string>) {
        console.log(`args: ${args}`);
    }
}

Build in types

 
// JSX: 

a : string = "Message";

var total : int  = 1;

var total : number = 2;


// Flow 
true : boolean 

"Message" : string

1234 : number

NaN : number


// TypeScript 


let a : boolean = true;

let a : number = 1;

let numbers : Array<number> = [];

let numbers : number[] = []; 

Arrays & typles

// Flow


var users: Array<string> = ["user1", "user2"];

var user: [string, string, number] = ['First', 'Last', 25];



// JSX


var users = new Array<string>(10); 

users = ['user1', 'user1', 'user3'];



// TypeScript

let users: string[] = ['User1', 'User1', 'user2'];


let matrix : number[][] = [
    [1, 2, 3, 4], 
    [1, 2, 3, 3], 
    [5, 6, 7, 8]
];

Maybe/any

 
// Flow


//@flow 

function serverRequest(
    endpoint: string, 
    method: ?string, body: ?object, 
    contentType : string = 'application/json' ) : Promise {
}


// TypeScript

function serverRequest(endpoint : string, method : any, 
                       body : any, contentType: string = 'application/json') : Promise {
    // do request
}


// ======================================================================================


// Post request

fetchResults('/endpoint', 'POST', {
    username: 'Some username',
    password: 'Some password'
}).then(/* process */);

Type Aliases & Generics

 
// Flow 


class Rhino { }

class Elephant { }


function animalFactory<T>() : T {
    return name == 'Rhino' ? Rhino() : Elephant();
};


let rhino : Rhino = animalFactory('Rhino');

let elephant : Elephant = animalFactory('Elephant');


// TypeScript 

class Rhino {}

class Elephant {}

function animalFactory<T>() : T {

};

let rhino = animalFactory<Rhino>();

let elephant = animalFactory<Elephant>();

Union / itersection types

 
// Flow 

class Rhino {}

class Elephant {}


type Animal = Rhino | Elephant;


type merging = {a : number } & { b : string };


type Exception =  Error | Warning;

type Error = { type: "Error", message: string };

type Warning = { type: "Warning", message: string };




Mixins: Flow

 
// Flow 

class Point mixins Sqarable, Drawable {

}

class Squarable {}

class Drawable {}

Interfaces

 
// TypeScript



interface Point {
    x: number,

    y: point,

    [declaredName: string]: any
}


interface User {
    name: string,
    job: ?string,
    age: ?number
}

Declaration: Flow

 
// Flow


declare class Counter {
    count: number
}


declare module Player {
    
    export class Track(name: String, id: number) {
        play(): number;
        id: number,
        name: string
    }

    declare function next() : void;

    declare function previous() : void;

    declare function track() : number;
}


declare interface Stack<T> {
    push(item: T): void;
    pop(): T;
    isEmpty(): bool;
}

Declaration: Typescript

 
// TypeScript

// animal-factory.d.ts


namespace animalFactory {
    interface AnimalOptions {
        name: string;
        height?: number;
        weight?: number;
    }
    function create(name: string, animalOptions?: AnimalOptions): Animal;
}

Declaration merging: Typescript

 
// TypeScript


interface A {
    name: string
}


interface A {
    age: number
}

Starter: flow

 
// TypeScript


// .babelrc 

{
   "presets": ["transform-flow-strip-types", "es2015"]
}

// .flowconfig

[include]
...

[ignore]
....

[declarations]
....

[libs]
....

Starter: TypeScript

 
// TypeScript


// tsconfig.json


{
    "compilerOptions": {
        "module": "commonjs",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "outFile": "../../built/local/tsc.js",
        "sourceMap": true
    },
    "exclude": [
        "node_modules",
        "wwwroot"
    ]
}

Real world: Flow

 
// Flow


// reducer.js

import Immutable from 'immutable';

type UsersState {
    title: string,
    users: ?Immutable.Set() 
}

let defaultState : UsersState = {
    title: 'Users page',
    users: Immutable.Set([])
}; 


export default function usersReducer (state: DefaultState = defaultState, 
    action: object) : UsersState {
    return state;
};

Real world: Flow

 
// Flow


// actions.js

export function addUser(username: string, email: string) : (f(res: object) : Promise) {
      return dispatch => {
        fetch('/usersEndpoint')
            .then(res => dispatch(res => res.json()))
            .then(res => dispatch(successResult(res)))
            .catch(err => dispatch(errorResult(err)));
      };
}

Demo time

Q / A

About me

  • twitter : ilavriv
  • GitHub : lavriv92

 

  • kottans.org
  • pllug.org.ua

Thank you

Types vs Types

By Ivan Lavriv

Types vs Types

  • 403