TypeScript Express 2020

CC-BY-NC-4.0 / Septembre 2019 / Loïc TRUCHOT

Don't miss the hype train

Forewords

  • reach a pro level for any kind of TS project
  • being able to begin with angular without any lack
  • be ready for the new war of JS transpilers
  • Share types in all JS environment

Angular oriented training

Install TypeScript

  • npm install -g typescript
  • npm install -g eslint
  • npm init
  • tsc --init
  • eslint --init
  • tsc -w
  • discover tsconfig.json

What would say a C# Dev

while discovering JavaScript ?

  • WTF is this abomination:
    • I want my types
    • I want my classes
    • I want my compiler
    • I want my autocompletion
    • I want my Microsoft stuff
  • So TS was born...

WHAT IS TYPESCRIPT ?

Static types

const playerName: string = 'Enzo';
function stopGame(player: string): boolean {
  console.log(`Game Over ${player}`);
  return false;
}
const isRunning: boolean = stopGame(playerName);

Before the = after the :

Workshop

const isValid = "3";
let familyName;
let age;
age = 8;
const isMarried = false;
let isAuth;
let welcomeSentence;
welcomeSentence = "Bienvenue"; 
const lang = "fr";

Type thoses variables

Ajouter des types à un projet existant

Why it's awesome

  • IDE intellisense & support
  • live in the future, with an always compatible JavaScript code
  • implicit documentation for everything
  • Get types for any existing framework/lib
  • learning curve hardness is your decision
  • compilation && errors
  • common readable base of work, for my team and the future me

Some cons

  • Please, don't forget JavaScript, especially ES5
  • JS is NOT Java (class/static types oriented)
  • Microsoft isn't always trusted in the JavaScript developer community
  • A lot of breaking change since the beginning

More types

  • null, undefined
  • any (all)
  • unknown (to define)
  • type inside a function
  • type outside a function

Workshop

Write and type those functions

  • Une fonction qui prend un boolean, et qui retourne l'inverse
  • Une fonction qui double un nombre
  • Une fonction qui vérifie si un nombre est pair
  • Une fonction qui vérifie si un nombre est impair
  • Une fonction qui ajoute un "s" à une string qu'on lui passe
  • Une fonction qui additionne deux chiffre et vérifie si  l'additition est inférieure à un troisième
  • Une fonction qui salue un utilisateur dans la console
  • Une fonction qui retourne toujours 42
const multiply = (x: number, y: number): number => x*y;

Union type

let antialiasing: 'x2' | 'x4' | 'x8' = 'x8';
// antialiasing = 'x16';
function chooseDifficulty(difficutly?: 'easy' | 'ironman'): 1 | 2 {
  return difficutly ? 1 : 2;
}
// chooseDifficulty('ironmann');
// optional arg
chooseDifficulty();

// be DRY we the Type keyword (alias)
type aa = 'x2' | 'x4' | 'x8';
let myDifficulty: aa = 'x8';

const setAA = (level: aa): void => {
  if (level === 'x8') {
    window.cancelAnimationFrame(0);
  }
};

Workshop

union

  • Produisez des variables avec les types hybrides suivants:
    • booléen ou null
    • any ou string - est-ce que ça un sens ?
    • string ou number
    • 1 ou 2 ou 3 ou 5 ou 8 ou 13
    • lundi ou mardi ou mercredi
    • Majeur ou Mineur
    • fonction ou null
type Jour = "lundi" | "mardi" | "mercredi" | number;
const j2: Jour = "mardi";

More types again

  • Inferred types...
  • Arrays
  • Tuples
  • Object

Workshop

const creature = {
    nom : "Basilic",
    description : `Le basilic est une bête légendaire, 
souvent présenté comme un reptile`,
    id : 1234 ,
    image : "Basilisk_aldrovandi.jpg",
    pouvoirs : ["empoisonnement", "petrification"]
}

const creatures = [creature, creature];

// what types ?

Type object and arrays

Keywords type & interfaces

  • Import / Export models
  • nested: like a classic object tree
  • optional: ? and Partial
  • mandatory: Required
  • protected: Readonly

classes

Finally a real class !

+ protected, readonly, abstract, static...

abstract class Animal {
    protected name: string;
    constructor(theName: string) { this.name = theName; }
  	getName() {
      return this.name;
    }
}
class Rhino extends Animal {
    private readonly isStrong: true;
    constructor() { super("Rhino"); }
}
class Employee {
    public name: string;
    constructor(theName: string) { this.name = theName; }
}
let animal: Animal;
let rhino: Rhino = new Rhino();
let employee: Employee = new Employee("Bob");
console.log(rhino.getName());
animal = rhino;
animal = employee; // Error: 'Animal' and 'Employee' are not compatible

Workshop

Write a class, matching the following conditions:

  • It describe a worker and his job
  • It receive as public properties:
    • a person name (readonly)
    • a job name
    • an annual salary
  • It produce value each 10 seconds: the salary / 1000
  • the produced value is a private property, beginning at 0
  • the method getValue() return the current value produced, anytime it's called

Interfaces

  • Just like type
  • But extendable
  • In between the type and the class
export type Player = {
  name: string;
  age: number;
};

export type PlayerService = {
  id: string;
  getPlayer: (s: string) => Player;
};

export interface IRequestService extends IService {
  get: (s: string) => string;
}
export interface IService {
  id: string;
}

export interface IGame {
  players: Player[];
  playerService: PlayerService;
  requestService: IRequestService;
  isRunning?: boolean;
  history: IGameData;
}

interface IGameData {
  [key: string]: string;
}

Generic types

  • A placeholder for a type
  • Already known, for Array<T>
type Identity<T> = (arg: T) => T;
const sameNumber: Identity<number> = (x) => x;
const n: number = sameNumber(3);
const s: string = sameNumber("test");

Decorators

Stole "annotation" from Python and transform it for JavaScript

const log = (
    target: any, 
    key: string, 
    descriptor: PropertyDescriptor
    ): any => {
  
    const method = descriptor.value;
    descriptor.value = function (...args: any[]): any {
        const s = JSON.stringify;
        const r = method.apply(this, args);
        console.log(`Call: ${key}(${s(args)}) => ${s(r)}`);
        return r;
    }
    return descriptor;
}

class Employee {
    public name: string;
    constructor(theName: string) { this.name = theName; }
    @log
    pay (salary: number) {
        return "your salary is:" + salary.toString();
    }
}

let employee: Employee = new Employee("Bob");
employee.pay(10000);
// Call: pay([10000]) => "your salary is:10000"

Clean syntaxe for an hidden wrapper for

  • classes
  • methods
  • props
  • functions
  • params...

THANK'S EVERYONE
It's finally done ! See you soon

TypeScript Express 2020

By Loïc TRUCHOT

TypeScript Express 2020

Discovering computer science basis with some JS examples

  • 378