Share
Embed
DevFest Paris 2019 - TypeScript: Why? When? How?
Slides from the talk I did at DevFest Paris 2019 with my mate Félix Billon!
Video (French): https://www.youtube.com/watch?v=Wf4W0T1bNNo
Sylvain PONTOREAU
February 08, 2019
Transcript
37 slides
-
Félix Billon Tech Lead @felix_billon Who we are? Sylvain Pontoreau
Field Engineer @spontoreau -
The beginning October, 2012: Preview April, 2014: version 1.0 Idea
was here, without the rest… -
The rebirth Late 2014: AtScript annoucement March, 2015: Angular 2
will be based on TypeScript September, 2016: Version 2.0! A lot of progress has been done since 1.0 (currently 3.x): • Performance improvement • Better integration with IDEs • Easier JavaScript library integration -
TypeScript & OSS Code Angular Ionic / Stencil rxjs NativeScript
TensorFlow.js NestJS Jest vue.js yarn -
You're in good company • Microsoft • Google • Slack
• Facebook • Ionic • Palantir • Ubisoft • Wix • Dashlane • … -
Types, why? Find errors at compile time instead of runtime
Improve code readability Less bugs Improve IDEs features: • Autocomplete • Code inspection • Refactoring -
Types in TypeScript boolean, number, string, array, void, null, undefined,
object Example: let str: string; let array: number[] = [1, 2, 3]; function fn(param: boolean): void { // Do something } -
Classes & Interfaces interface Rocket { boosters: number; launch: ()
=> void; } class Soyuz implements Rocket { boosters : number; constructor() { this.boosters = 4; } launch(): void { … }; } let soyuzT15: Rocket = new Soyuz(); let soyuzMS3: Soyuz = new Soyuz(); Class or Interface… How to choose? -
Types, how? Take care of the any special type Types
are only useful at compile time Compiler can infer types Duck typing != nominal typing -
Duck typings class Rocket { name: string; boosters: number; }
class Cat { name: string; } function playWithKitten(kitten: Cat) { // Do something } const rocket: Rocket = { name: "Soyuz", boosters: 4 }; const cat: Cat = { name: "Grumpy" }; playWithKitten(cat); playWithKitten(rocket); // ☺ -
Definition files Describe and type JavaScript code NPM package &
TypeScript: • Wrote in TypeScript • Wrote in JavaScript + definition included • Wrote in JavaScript without definition ✋ • Definition package required (@types) DefinitelyTyped lib.d.ts -
Definition files Installation: { "name": "angular-with-dts", "version": "1.0.0", "dependencies": {
"angular": "1.5.8" }, "devDependencies": { "@types/angular":"1.5.20" } } $ npm install --save-dev @types/angular package.json: -
Abstraction Asbtract classes & methods: abstract class Rocket { boosters:
string; abstract launch(): void; } class Soyuz extends Rocket { } class Soyuz extends Rocket { launch(): void { throw new Error("Not implemented."); } } -
Back to interfaces Optional: interface Rocket { boosters: number; launch?:
() => void; } Read-only: interface Rocket { readonly boosters: number; launch?: () => void; } interface Launch { () => void; } Function: Cannot be implemented by a class ! -
Generics An example with the Factory pattern: abstract class Rocket
{ readonly boosters: number; constructor(boosters: number) { this.boosters = boosters; } abstract launch() : void; } class RocketFactory<T extends Rocket> { ctor: new (boosters: number) => T; constructor(ctor: new (boosters: number) => T) { this.ctor = ctor; } create(boosters: number): T { return new this.ctor(boosters); } } -
Asynchronous Example: getRockets(): Promise<Rocket> { return fetch("http://rockets-api.com") .then((response) => {
return response.json(); }); } async getRockets(): Promise<Rocket> { const res = await fetch("…"); return await res.json(); } ES3+ compability -
Modules, TypeScript to the rescue! Export: Import: Compatibility: Common, AMD,
UMD, System, ES2015 Only one will survive: ES2015! export class Rocket { // … } import { Rocket } from "./rocket"; -
Decorators Currently experimental! Can be apply on: • Classes •
Methods • Properties • Parameters TC 39: Stage 2 Draft "experimentalDecorators": true, "emitDecoratorMetadata": true, -
Decorators const track: MethodDecorator = ( target: any, key: string
| symbol, descriptor: PropertyDescriptor ) => { const calledFunction = descriptor.value; const newFunction = function() { Telemetry.Track({ className: target.constructor.name, methodName: key.toString(), parameters: arguments }); return calledFunction.apply(this, arguments); }; descriptor.value = newFunction; return descriptor; }; -
Decorators Usage: class Rocket { orientation: Vector3 = new Vector3(0.0,
0.0, 1.0); @track correctPath(vector: Vector3) { this.orientation.add(vector); } } const rocket = new Rocket(); // Telemetry will track: // {"className":"Rocket","methodName":"correctPath","parameters":{"0":{"x":0.1,"y":0.2,"z":0}}} rocket.correctPath(new Vector3(0.1, 0.2, 0.0)); -
tsconfig.json • A configuration file that contains compiler options! •
Can be initialized with the CLI: • Example: { "compilerOptions": { "target": "es5", "module": "es2015", "removeComments": true, "sourceMap": true }, "include": [ "src/**/*" ] } $ tsc --init -
Zoom on compilation’s options { "compilerOptions": { "target": "es5", "module":
"es2015", "sourceMap": true, "importHelpers": true, "noEmitHelpers": true, "strict": true, "lib": ["es6", "dom"], … } } • Barely hundred compilation’s options • Some important options: -
JavaScript to TypeScript A line of JavaScript is a line
of TypeScript $ tsc --init -
JavaScript to TypeScript Check JavaScript code with TypeScript • For
a single file: // @ts-check • Overall (tsconfig.json): checkJs: true function sum(numbers) { return numbers .reduce(function(previous, next) { return previous + next; }); } var result = sum([true, 2, "3"]); console.log(result); // 33 ... // @ts-check /** * @param {number[]} numbers */ function sum(numbers) { return numbers .reduce(function(previous, next) { return previous + next; }); } var value = sum([true, 2, "3"]); console.log(result); // 33 ... -
Conclusion • Take care, TypeScript !== C#, Java, … •
The community is amazing • TypeScript have an influence on JavaScript • Evolutivity, Maintenability, Scalability • Great tools!