À la découverte de
Denis Voituron
Agenda
• Installation
• JavaScript Strongly Typed
• Object Oriented Programming
• Find your Data with LINQ
• Asynchronous Programming
• Bests Practices
• Advantages and Disadvantages
• Conclusion
Historique
EcmaScript
ES8
(ES2017)
ES7
(ES2016)
ES6
(ES2015)
ES5
ES3
JavaScript
Problèmes du langage
• Langage interprété
• Absence de modules
• Typage faible
• Conversions automatiques
• Portée (this)
• Manque de types statiques
Programming language
Superset of JavaScript
Transpiled into JavaScript
Open Source
Developped by Microsoft, supported by Google
lang.org
«Microsoft's TypeScript may be the best of the
many Javascript front ends. It seems to generate
the most attractive code.»
https://insights.stackoverflow.com/survey/2018
Installation
Installation
• Visual Studio Code : https://code.visualstudio.com
• NodeJS et NPM : https://nodejs.org
• TypeScript :
• http-Server (Node) :
npm install TypeScript -g
npm install http-server -g
Reload Window
& Open TS file
Specifies the folder path containing
the tsserver and lib*.d.ts files to use.
Sample
function startGame() {
var myMessage = document.getElementById("message");
myMessage.innerText = "Hello world";
}
document.getElementById("btnStart").addEventListener("click", startGame);
HelloWorld.ts
<html>
<body>
<div id="message"></div>
<button id="btnStart">Start</button>
<script src="HelloWorld.js"></script>
</body>
</html>
Index.html
tsc HelloWorld.ts
tsconfig.json
• Target ECMAScript 5
• SourceMap Debugging in Chrome
• Strict Object is possibly 'null’
• Watch Run ‘tsc’ and update files
• …
{
"compilerOptions": {
"target": "es5",
"noImplicitAny": true,
"sourceMap": true,
"watch": true,
"strict": true,
"removeComments": true,
"outDir": "./dist"
},
"include": [
"./**/*.ts"
],
"exclude": [
"node_modules"
]
}
tsconfig.json
tsc --init
https://html5test.com
Tasks.json
Basic Types
Boolean - Number - String - Array - Enum
var name: string = "Denis"
var age: number = 21
var birthdate: Date;
var name = "Denis";
var age = 21;
var birthdate;
birthdate.
Declarations with let and const
console.log(someString);
var someString = "hello World";
let someString = "hello World";
console.log(someString);
const someString = "hello World";
someString = "a new World";
Type Annotations and Type Inference
let x: string = "Hello World";
x = 42;
let x = "Hello World";
x = 42;
let name: string = "Voituron";
let message = `My name is ${name}`;
Union Types, Null, Undefined
{
"compilerOptions": {
"strictNullChecks": true,
...
let x: string;
x = null;
x = undefined;
let y: string | null;
y = null;
y = undefined;
let z: string | number | null;
z = null;
z = "Hello";
z = 123;
Type Assertions
let value: any = 5;
let fixedString: string = (<number>value).toFixed(4);
console.log(fixedString) // 5.0000
let value: any = 5;
let fixedString: string = (value as number).toFixed(4);
console.log(fixedString) // 5.0000
Demo
+ showSolution(HTMLElement): void
+ play(): void
- checkSolution(): Boolean
+ static solution: RowOfBalls
+ static rows: RowOfBalls[ ]
+ color: Colors
+ isClickable: boolean
+ render(): HTMLImageElement
+ render(): HTMLElement
+ Red
+ Green
+ Yellow
+ Blue
+ White
+ balls: Ball[ ]
+ isClickable: boolean
+ goodBalls: number
+ render(): HTMLImageElement
Method
function getSurface(width: number): number {
return width * width;
}
function getSurface(width): number {
return width * width;
}
[ts] Parameter 'width' implicitly
has an 'any' type.
Overloaded Methods
// Signatures
function getSurface(width: number): number;
function getSurface(width: number, height: number): number;
// Main method
function getSurface(width: number, height?: number): number {
if (height == null)
return width * width;
else
return width * height;
}
Default value
function getSurface(width: number, height: number = width): number {
return width * height;
}
getSurface(10); // 100
getSurface(10, 5); // 50
Anonymous methods
let square = (x: number) => x * x;
square(2); // 4
let add = (a: number, b: number) => a + b;
add(2, 3); // 5
let add = (a: number, b: number) => { return a + b };
Static Members
class WebDeveloper extends Developer {
static jobDescription = "Build cool things";
static logFavoriteProtocol() {
console.log("HTTPS, of course");
}
writeTypeScript(): void {
console.log(WebDeveloper.jobDescription);
}
}
Generic
"lib": [ "es6" ]
let list = new Set<number>([0, 1]);
list.add(2)
let dico = new Map<string, number>([["k1", 0], ["k2", 1]]);
dico.set("k1", 2);
let array = new Array<string>();
array.push("Hello");
Generic
class Queue {
private data = [];
push = (item) => this.data.push(item);
pop = () => this.data.shift();
}
const queue = new Queue();
queue.push(0);
queue.push("1"); // RUNTIME ERROR
"lib": [ "es6" ]
Generic
class QueueNumber {
private data = [];
push = (item: number) => this.data.push(item);
pop = (): number => this.data.shift();
}
const queue = new QueueNumber();
queue.push(0);
queue.push("1"); // COMPILATION ERROR
class Queue<T> {
private data = [];
push = (item: T) => this.data.push(item);
pop = (): T => this.data.shift();
}
const queue = new Queue<number>();
queue.push(0);
queue.push("1"); // COMPILATION ERROR
Interfaces vs Classes
Classes
Define a new type
Properties (with implementation)
Methods (with implémentation)
Can be instantiated
Interfaces
Define a new type
Properties (signatures)
Methods (signatures)
Cannot be instantiated
Interfaces
interface Employee {
name: string;
title: string;
}
interface Manager extends Employee {
department: string;
numOfEmployees: number;
scheduleMeeting: (topic: string) => void;
}
let developer: Employee = {
name: "Voituron",
title: "Developer"
}
Classes
Module Oniryx.Myproject {
class Developer {
department: string;
private _title : string;
public get title() : string {
return this._title;
}
public set title(value : string) {
this._title = value;
}
public requirements(value: string): void {
console.log(value);
}
Extending a class, implementing an interface
class WebDeveloper extends Developer {
favoriteEditor: string;
writeTypeScript(): void {
// Write code
}
}
/// <reference path="Employee.ts" />
class Engineer implements Employee {
name: string;
title: string;
}
Constructors
class Developer {
public department: string;
public title: string;
constructor() {
console.log("Creating a new developer");
}
}
Constructors
class Developer {
public department: string;
public title: string;
constructor() {
console.log("Creating a new developer");
}
}
class WebDeveloper extends Developer {
readonly favoriteEditor: string;
constructor(editor: string) {
super();
this.favoriteEditor = editor;
}
}
Constructors
class Developer {
constructor(public department: string, public title: string) {
console.log("Creating a new developer");
}
}
class WebDeveloper extends Developer {
readonly favoriteEditor: string;
constructor(editor: string) {
super();
this.favoriteEditor = editor;
}
}
Extension methods
// global.d.ts
interface Date {
isInFuture(): boolean;
}
Date.prototype.isInFuture = function(): boolean {
return (this != null && this.valueOf() > Date.now());
}
Modules
• CommonJS
• SystemJS
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"traceResolution": true,
default
Exporting a declaration
export interface Person { }
class Manager { } // Not accessible outside the module
import { Person } from "./Person";
let manager: Person
Exporting a declaration
export interface Person { }
class Manager { } // Not accessible outside the module
import * as People from "./Person";
let manager: People.Person
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.0/system.js"></script>
<script>
SystemJS.config({
map: {
jquery: 'https://code.jquery.com/jquery.js'
},
packages: {
'.': { defaultExtension: 'js' }
}
});
SystemJS.import("./MyApp.js");
</script>
Module loader in browser
• Module are dynamically loaded (via SystemJS).
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.0/system.js"></script>
<script>
SystemJS.config({
map: {
jquery: 'https://code.jquery.com/jquery.js',
linqts: '/node_modules/linqts/dist/linqts.js'
},
packages: {
'.': { defaultExtension: 'js' }
}
});
SystemJS.import("./MyApp.js");
</script>
Linq for TypeScript
• SystemJS Loader
npm install linqts
https://github.com/kutyel/linq.ts
Linq for TypeScript https://github.com/kutyel/linq.ts
import { List } from "linqts"
const arr = new List<number>([1, 2, 3, 4, 5])
.Where(x => x > 3)
.Select(y => y * 2)
.ToArray(); // > [8, 10]
Linq for TypeScript https://github.com/kutyel/linq.ts
npm install linqts
import { List } from "linqts"
let people = new List([
{ Name: "Alice", Age: 25 },
{ Name: "Bob", Age: 50 },
{ Name: "Kathy", Age: 15 }
]);
let alice = people.FirstOrDefault(i => i.Age > 18).Name;
Linq for TypeScript https://github.com/kutyel/linq.ts
Project Select
Filter Where, Distinct
Test Any, All
Join Join
Group GroupBy, Group Join
Aggregate Count, Min, Max, Sum, Avg
Partition Skip, SkipWhile, Take, TakeWhile
Set Union, Intersect, Except
Order OrderBy, OrderByDescending
Async / Await
• Promiseclass HelloWorld {
public delay(ms: number): Promise<void> {
return new Promise<void>((resolve) => {
setTimeout(resolve, ms);
});
}
}
A Promise is an object representing the eventual
completion or failure of an asynchronous operation.
"compilerOptions": {
"target": "es5",
"lib": [
"es6", "dom"
]
},
Async / Await
• Promise
• async / await
class HelloWorld {
public delay(ms: number): Promise<void> {
return new Promise<void>((resolve) => {
setTimeout(resolve, ms);
});
}
public async asyncAwait(): Promise<void> {
document.write("Knock, knock! <br/>");
await this.delay(3000); // 3 seconds
document.write("Who's there? <br/>");
}
}
new HelloWorld().asyncAwait(); // Start
Compile and Build tsconfig.json
{
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"problemMatcher": [ "$tsc“ ],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
.vscodetasks.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"traceResolution": true,
"noImplicitAny": true,
"sourceMap": true,
"watch": true,
"strict": true,
"strictNullChecks": true,
"removeComments": true,
"outDir": "./dist",
"lib": [ "es6", "dom" ]
},
"include": [
"./**/*.ts"
],
"exclude": [
"node_modules"
]
}
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.0/system.js">
</script>
<script>
SystemJS.config({
map: {
jquery: 'https://code.jquery.com/jquery.js',
linqts: '/node_modules/linqts/dist/linqts.js'
},
packages: {
'.': { defaultExtension: 'js' }
}
});
SystemJS.import("./MyApp.js");
</script>
Module Loader
Do's and Don'ts
• General Types
• Callback Types
• Optional Parameters in Callbacks
• Overloads and Callbacks
• Function Overloads
https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html
Programming language
Superset of JavaScript
Transpiled into JavaScript
Open Source
Developped by Microsoft, supported by Google
lang.org
Slides: https://slideshare.net/dvoituron
Code: https://github.com/dvoituron /TypeScriptMasterMind (branches)

A la découverte de TypeScript

  • 1.
    À la découvertede Denis Voituron
  • 2.
    Agenda • Installation • JavaScriptStrongly Typed • Object Oriented Programming • Find your Data with LINQ • Asynchronous Programming • Bests Practices • Advantages and Disadvantages • Conclusion
  • 3.
  • 4.
  • 5.
    JavaScript Problèmes du langage •Langage interprété • Absence de modules • Typage faible • Conversions automatiques • Portée (this) • Manque de types statiques
  • 6.
    Programming language Superset ofJavaScript Transpiled into JavaScript Open Source Developped by Microsoft, supported by Google lang.org
  • 7.
    «Microsoft's TypeScript maybe the best of the many Javascript front ends. It seems to generate the most attractive code.» https://insights.stackoverflow.com/survey/2018
  • 9.
  • 10.
    Installation • Visual StudioCode : https://code.visualstudio.com • NodeJS et NPM : https://nodejs.org • TypeScript : • http-Server (Node) : npm install TypeScript -g npm install http-server -g
  • 11.
    Reload Window & OpenTS file Specifies the folder path containing the tsserver and lib*.d.ts files to use.
  • 12.
    Sample function startGame() { varmyMessage = document.getElementById("message"); myMessage.innerText = "Hello world"; } document.getElementById("btnStart").addEventListener("click", startGame); HelloWorld.ts <html> <body> <div id="message"></div> <button id="btnStart">Start</button> <script src="HelloWorld.js"></script> </body> </html> Index.html tsc HelloWorld.ts
  • 13.
    tsconfig.json • Target ECMAScript5 • SourceMap Debugging in Chrome • Strict Object is possibly 'null’ • Watch Run ‘tsc’ and update files • … { "compilerOptions": { "target": "es5", "noImplicitAny": true, "sourceMap": true, "watch": true, "strict": true, "removeComments": true, "outDir": "./dist" }, "include": [ "./**/*.ts" ], "exclude": [ "node_modules" ] } tsconfig.json tsc --init https://html5test.com
  • 14.
  • 16.
    Basic Types Boolean -Number - String - Array - Enum var name: string = "Denis" var age: number = 21 var birthdate: Date; var name = "Denis"; var age = 21; var birthdate; birthdate.
  • 17.
    Declarations with letand const console.log(someString); var someString = "hello World"; let someString = "hello World"; console.log(someString); const someString = "hello World"; someString = "a new World";
  • 18.
    Type Annotations andType Inference let x: string = "Hello World"; x = 42; let x = "Hello World"; x = 42; let name: string = "Voituron"; let message = `My name is ${name}`;
  • 19.
    Union Types, Null,Undefined { "compilerOptions": { "strictNullChecks": true, ... let x: string; x = null; x = undefined; let y: string | null; y = null; y = undefined; let z: string | number | null; z = null; z = "Hello"; z = 123;
  • 20.
    Type Assertions let value:any = 5; let fixedString: string = (<number>value).toFixed(4); console.log(fixedString) // 5.0000 let value: any = 5; let fixedString: string = (value as number).toFixed(4); console.log(fixedString) // 5.0000
  • 22.
    Demo + showSolution(HTMLElement): void +play(): void - checkSolution(): Boolean + static solution: RowOfBalls + static rows: RowOfBalls[ ] + color: Colors + isClickable: boolean + render(): HTMLImageElement + render(): HTMLElement + Red + Green + Yellow + Blue + White + balls: Ball[ ] + isClickable: boolean + goodBalls: number + render(): HTMLImageElement
  • 23.
    Method function getSurface(width: number):number { return width * width; } function getSurface(width): number { return width * width; } [ts] Parameter 'width' implicitly has an 'any' type.
  • 24.
    Overloaded Methods // Signatures functiongetSurface(width: number): number; function getSurface(width: number, height: number): number; // Main method function getSurface(width: number, height?: number): number { if (height == null) return width * width; else return width * height; }
  • 25.
    Default value function getSurface(width:number, height: number = width): number { return width * height; } getSurface(10); // 100 getSurface(10, 5); // 50
  • 26.
    Anonymous methods let square= (x: number) => x * x; square(2); // 4 let add = (a: number, b: number) => a + b; add(2, 3); // 5 let add = (a: number, b: number) => { return a + b };
  • 27.
    Static Members class WebDeveloperextends Developer { static jobDescription = "Build cool things"; static logFavoriteProtocol() { console.log("HTTPS, of course"); } writeTypeScript(): void { console.log(WebDeveloper.jobDescription); } }
  • 28.
    Generic "lib": [ "es6"] let list = new Set<number>([0, 1]); list.add(2) let dico = new Map<string, number>([["k1", 0], ["k2", 1]]); dico.set("k1", 2); let array = new Array<string>(); array.push("Hello");
  • 29.
    Generic class Queue { privatedata = []; push = (item) => this.data.push(item); pop = () => this.data.shift(); } const queue = new Queue(); queue.push(0); queue.push("1"); // RUNTIME ERROR "lib": [ "es6" ]
  • 30.
    Generic class QueueNumber { privatedata = []; push = (item: number) => this.data.push(item); pop = (): number => this.data.shift(); } const queue = new QueueNumber(); queue.push(0); queue.push("1"); // COMPILATION ERROR class Queue<T> { private data = []; push = (item: T) => this.data.push(item); pop = (): T => this.data.shift(); } const queue = new Queue<number>(); queue.push(0); queue.push("1"); // COMPILATION ERROR
  • 31.
    Interfaces vs Classes Classes Definea new type Properties (with implementation) Methods (with implémentation) Can be instantiated Interfaces Define a new type Properties (signatures) Methods (signatures) Cannot be instantiated
  • 32.
    Interfaces interface Employee { name:string; title: string; } interface Manager extends Employee { department: string; numOfEmployees: number; scheduleMeeting: (topic: string) => void; } let developer: Employee = { name: "Voituron", title: "Developer" }
  • 33.
    Classes Module Oniryx.Myproject { classDeveloper { department: string; private _title : string; public get title() : string { return this._title; } public set title(value : string) { this._title = value; } public requirements(value: string): void { console.log(value); }
  • 34.
    Extending a class,implementing an interface class WebDeveloper extends Developer { favoriteEditor: string; writeTypeScript(): void { // Write code } } /// <reference path="Employee.ts" /> class Engineer implements Employee { name: string; title: string; }
  • 35.
    Constructors class Developer { publicdepartment: string; public title: string; constructor() { console.log("Creating a new developer"); } }
  • 36.
    Constructors class Developer { publicdepartment: string; public title: string; constructor() { console.log("Creating a new developer"); } } class WebDeveloper extends Developer { readonly favoriteEditor: string; constructor(editor: string) { super(); this.favoriteEditor = editor; } }
  • 37.
    Constructors class Developer { constructor(publicdepartment: string, public title: string) { console.log("Creating a new developer"); } } class WebDeveloper extends Developer { readonly favoriteEditor: string; constructor(editor: string) { super(); this.favoriteEditor = editor; } }
  • 38.
    Extension methods // global.d.ts interfaceDate { isInFuture(): boolean; } Date.prototype.isInFuture = function(): boolean { return (this != null && this.valueOf() > Date.now()); }
  • 39.
    Modules • CommonJS • SystemJS { "compilerOptions":{ "target": "es5", "module": "commonjs", "moduleResolution": "node", "traceResolution": true, default
  • 40.
    Exporting a declaration exportinterface Person { } class Manager { } // Not accessible outside the module import { Person } from "./Person"; let manager: Person
  • 41.
    Exporting a declaration exportinterface Person { } class Manager { } // Not accessible outside the module import * as People from "./Person"; let manager: People.Person
  • 42.
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.0/system.js"></script> <script> SystemJS.config({ map: { jquery:'https://code.jquery.com/jquery.js' }, packages: { '.': { defaultExtension: 'js' } } }); SystemJS.import("./MyApp.js"); </script> Module loader in browser • Module are dynamically loaded (via SystemJS).
  • 44.
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.0/system.js"></script> <script> SystemJS.config({ map: { jquery:'https://code.jquery.com/jquery.js', linqts: '/node_modules/linqts/dist/linqts.js' }, packages: { '.': { defaultExtension: 'js' } } }); SystemJS.import("./MyApp.js"); </script> Linq for TypeScript • SystemJS Loader npm install linqts https://github.com/kutyel/linq.ts
  • 45.
    Linq for TypeScripthttps://github.com/kutyel/linq.ts import { List } from "linqts" const arr = new List<number>([1, 2, 3, 4, 5]) .Where(x => x > 3) .Select(y => y * 2) .ToArray(); // > [8, 10]
  • 46.
    Linq for TypeScripthttps://github.com/kutyel/linq.ts npm install linqts import { List } from "linqts" let people = new List([ { Name: "Alice", Age: 25 }, { Name: "Bob", Age: 50 }, { Name: "Kathy", Age: 15 } ]); let alice = people.FirstOrDefault(i => i.Age > 18).Name;
  • 47.
    Linq for TypeScripthttps://github.com/kutyel/linq.ts Project Select Filter Where, Distinct Test Any, All Join Join Group GroupBy, Group Join Aggregate Count, Min, Max, Sum, Avg Partition Skip, SkipWhile, Take, TakeWhile Set Union, Intersect, Except Order OrderBy, OrderByDescending
  • 49.
    Async / Await •Promiseclass HelloWorld { public delay(ms: number): Promise<void> { return new Promise<void>((resolve) => { setTimeout(resolve, ms); }); } } A Promise is an object representing the eventual completion or failure of an asynchronous operation. "compilerOptions": { "target": "es5", "lib": [ "es6", "dom" ] },
  • 50.
    Async / Await •Promise • async / await class HelloWorld { public delay(ms: number): Promise<void> { return new Promise<void>((resolve) => { setTimeout(resolve, ms); }); } public async asyncAwait(): Promise<void> { document.write("Knock, knock! <br/>"); await this.delay(3000); // 3 seconds document.write("Who's there? <br/>"); } } new HelloWorld().asyncAwait(); // Start
  • 52.
    Compile and Buildtsconfig.json { "version": "2.0.0", "tasks": [ { "type": "typescript", "tsconfig": "tsconfig.json", "problemMatcher": [ "$tsc“ ], "group": { "kind": "build", "isDefault": true } } ] } .vscodetasks.json { "compilerOptions": { "target": "es5", "module": "commonjs", "moduleResolution": "node", "traceResolution": true, "noImplicitAny": true, "sourceMap": true, "watch": true, "strict": true, "strictNullChecks": true, "removeComments": true, "outDir": "./dist", "lib": [ "es6", "dom" ] }, "include": [ "./**/*.ts" ], "exclude": [ "node_modules" ] }
  • 53.
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.0/system.js"> </script> <script> SystemJS.config({ map: { jquery:'https://code.jquery.com/jquery.js', linqts: '/node_modules/linqts/dist/linqts.js' }, packages: { '.': { defaultExtension: 'js' } } }); SystemJS.import("./MyApp.js"); </script> Module Loader
  • 54.
    Do's and Don'ts •General Types • Callback Types • Optional Parameters in Callbacks • Overloads and Callbacks • Function Overloads https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html
  • 55.
    Programming language Superset ofJavaScript Transpiled into JavaScript Open Source Developped by Microsoft, supported by Google lang.org
  • 56.