Slide 1

Slide 1 text

A TypeScript journey Microsoft Ignite The Tour - Paris 2019 Sylvain Pontoreau Terance Moussoki Paul Souche Félix Billon

Slide 2

Slide 2 text

Paris TypeScript

Slide 3

Slide 3 text

@ParisTypeScript Who we are and how to contact us @spontoreau @MoussokiT @lsagetlethias @felix_billon @paulsouche

Slide 4

Slide 4 text

Part 1: Let’s get started

Slide 5

Slide 5 text

What's the problem with JavaScript? Let's take a look on some code!

Slide 6

Slide 6 text

Types are an advantage • Errors at compile time instead of runtime • Code readability, maintenability & scalability • Less bugs (average: -15%) • IDEs (Autocomplete, code inspection, refactoring) • Type inference const hello = "Hello world!";

Slide 7

Slide 7 text

Type capabilities • Primitive types: number, string, boolean • Special types: any, void, unknow • Classes (constructor, abstract, inheritance, access modifiers, …) • Interface (can be used by TypeScript to check object structure) • Type alias const value: number = 1; type one = 1;

Slide 8

Slide 8 text

But take care • Any everywhere isn’t a solution (you’re doing JavaScript…) • Nominal typing • Structural typing • So TypeScript !== C#, Java • Strict mode is recommanded

Slide 9

Slide 9 text

How it works?

Slide 10

Slide 10 text

Some features

Slide 11

Slide 11 text

Generic An exemple with the Factory pattern: abstract class Rocket { constructor( public readonly boosters : number ) { } abstract launch() : void; } class RocketFactory { ctor: new (boosters: number) => T; constructor(ctor: new (boosters: number) => T) { this.ctor = ctor; } create(boosters: number): T { return new this.ctor(boosters); } }

Slide 12

Slide 12 text

Generic Generic & type system: // type alias type Rocket = { id: number; model: string; boosters: number; }; // Mapped type type Partial = { [K in keyof T]?: T[K]; }; const e: Partial = { }; // Conditional type Exclude = T extends U ? never: T; type Keys = Exclude; You will have more information about that in Part 2

Slide 13

Slide 13 text

Decorators Currently experimental! Can be apply on: • Classes • Methods • Properties • Parameters TC 39: Draft "experimentalDecorators": true, "emitDecoratorMetadata": true,

Slide 14

Slide 14 text

Decorators const track: MethodDecorator = ( target: any, key: string | symbol, descriptor: PropertyDescriptor ) => { const calledFunction = descriptor.value; const newFunction = (this: any, ...args:any[]) { Telemetry.Track({ className: target.constructor.name, methodName: key.toString(), parameters: args }); return calledFunction.apply(target, args); }; descriptor.value = newFunction; return descriptor; };

Slide 15

Slide 15 text

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));

Slide 16

Slide 16 text

Demo

Slide 17

Slide 17 text

There is more... More to come in the second part

Slide 18

Slide 18 text

Question?

Slide 19

Slide 19 text

Merci J

Slide 20

Slide 20 text

Part 2: TypeScript beyond the basics

Slide 21

Slide 21 text

Summary ● Advanced Types (12.5 min) Paul ○ never / unknown / type alias / as const ○ literal / index types ○ union | Intersection ○ type guards ○ mapped / conditional types ● Strict mode (15 min) Félix ○ strictNullChecks ○ noImplicitAny ○ noImplicitThis ○ strictFunctionTypes ○ alwaysStrict ○ strictBindCallApply ○ strictPropertyInitialisation

Slide 22

Slide 22 text

Summary ● Compiler (12.5 min) Paul ○ declarations / declarationDir ○ listFiles / noEmit ○ allowJs / checkJS ○ noEmitHelpers / importHelpers ○ lib / typeRoots / types resolution ○ moduleResolution ○ baseUrl / paths ○ esModuleInterop / allowSyntheticDefaultImports ● TypeScript 3.7 (5 min) Félix ○ Tc39 features ○ + ts features

Slide 23

Slide 23 text

Advanced Types

Slide 24

Slide 24 text

Never / unknown / type alias / as const (1 / 4) link Type never represents the type of values that never occur - Raised exceptions - Infinite Loops - Conditional types fallback

Slide 25

Slide 25 text

Never / unknown / type alias / as const (2 / 4) link Type unknown acts like any but type safely : it must be casted - Used in type guards - Useful when type is unnecessary (proxy)

Slide 26

Slide 26 text

Never / unknown / type alias / as const (3 / 4) link Type alias is a “type variable” - Shorten long combinaison of union, intersection, mapped types

Slide 27

Slide 27 text

Never / unknown / type alias / as const (4 / 4) link Cast as const returns a readonly literal type

Slide 28

Slide 28 text

Literal / index types (1 / 2) link A literal type defines the exact value of a type it can be string, numeric or even object (as const)

Slide 29

Slide 29 text

Literal / index types (2 / 2) link With index types the compiler checks code that use dynamic property names

Slide 30

Slide 30 text

Union / Intersection (1 / 2) link An union type is actually the “intersection” of its members

Slide 31

Slide 31 text

Union / Intersection (2 / 2) link An intersection type is actually the “union” of its members

Slide 32

Slide 32 text

Type Guards (1 / 3) link A type guard is a runTime check that can be interpreted in control flow Built-in type guards : typeof, Array.isArray, instanceOf

Slide 33

Slide 33 text

Type Guards (2 / 3) link Most of the time we use it with a literal type

Slide 34

Slide 34 text

Type Guards (3 / 3) link And if not an union type

Slide 35

Slide 35 text

Mapped / Conditional types (1 / 6) link A mapped type is a “function type” that takes a type and map it thanks to indexable types

Slide 36

Slide 36 text

Mapped / Conditional types (2 / 6) link Very powerful to transform types

Slide 37

Slide 37 text

Mapped / Conditional types (3 / 6) link A conditional type selects one of two possible types based on a condition

Slide 38

Slide 38 text

Mapped / Conditional types (4 / 6) link Unleash power of both

Slide 39

Slide 39 text

Mapped / Conditional types (5 / 6) link Unleash power of both

Slide 40

Slide 40 text

Mapped / Conditional types (6 / 6) link Unleash power of both

Slide 41

Slide 41 text

Strict mode

Slide 42

Slide 42 text

Strict mode ? - one of the most important option ! - compilation’s option that enforce strict typings - master option’s that activate some sub-option : - strictNullChecks - noImplicitAny - noImplicitThis - strictFunctionTypes - alwaysStrict - strictBindCallApply - strictPropertyInitialisation

Slide 43

Slide 43 text

How activate Strict mode - On new project use tsc --init, strict option will be activated - In tsconfig.json file, strict is deactivated by default - On existing project it can be adopted incrementally :

Slide 44

Slide 44 text

--strictNullChecks (1/4) - By default, null and undefined are included in other type in imlipicit way - --strictNullChecks make them apart type, it needs to be explicit

Slide 45

Slide 45 text

--strictNullChecks (2/4) link - Exemple

Slide 46

Slide 46 text

--strictNullChecks (3/4) - To handle null and undefined you can use : - Union type : link - Type Guard : link

Slide 47

Slide 47 text

--strictNullChecks (4/4) link - In some specific case you can use non-null assertion operator “!” - Be careful with non-null assertion operator cause you enforce TypeScript’s compiler behavior.

Slide 48

Slide 48 text

--noImplicitAny link - any is a dangerous type and he can be : - explicit : you wrote any - implicit : use by TypeScript’s compiler when type is not explicit and it can’t infer it. - --noImpliciteAny raised error when second case appear

Slide 49

Slide 49 text

--noImplicitThis (1/2) link - TypeScript’s compiler try to infer this in function’s body - If compiler can’t infer it, --noImplicitThis will raised an error

Slide 50

Slide 50 text

--noImplicitThis (2/2) link - You can enforce the type of this by typings it as a first argument in a function

Slide 51

Slide 51 text

--strictPropertyInitialisation (1/2) link - when activate, the type checker verifies that each class’s property : - has a type that include undefined - has been initialized during déclaration - has been initialized in the constructor - Exemple

Slide 52

Slide 52 text

--strictPropertyInitialisation (2/2) link - In some specific case you can use definite assignment assertion operator “!”

Slide 53

Slide 53 text

Compiler

Slide 54

Slide 54 text

declarations / declarationDir (1 / 1) - --declarations is a flag to output or not the declarations (default false) - It is available through the cli - Used when need to publish declaration for a consumer - --declarationDir is the relative path where to output declarations files (same as --outDir if not provided) - It is available through the cli - To publish the code on a registry use “types” key in package.json to refer to the declarations entry (index.d.ts) by default

Slide 55

Slide 55 text

listFiles / noEmit (1 / 1) - --listFiles is a flag to output the files part of the transpilation (default false) - It is available through the cli - Useful for debug - --noEmit is a flag to not emit any file but just typecheck the code (default false) - It is available through the cli - Useful for scripts executed by ts-node or tests

Slide 56

Slide 56 text

allowJs / checkJs (1 / 1) - --allowJs is a flag to allow to import JavaScript files (default false) - It is available through the cli - No need for this flag for JavaScript in node_modules (TypeScript will resolve declarations) - --checkJs is a flag to try type checking on JavaScript files - It is available through the cli - Same as @ts-check in a JavaScript file

Slide 57

Slide 57 text

noEmitHelpers / importHelpers (1 / 2) - --noEmitHelpers is a flag to not Emit helpers functions when targeting old browsers or node versions - It is available through the cli - async / await is available in es3

Slide 58

Slide 58 text

noEmitHelpers / importHelpers (2 / 2) - --importHelpers is a flag to Emit tslib imports when targeting old browsers - It is available through the cli - Need tslib as dependency

Slide 59

Slide 59 text

- --lib is a list of lib files to includes during transpilation - It is available through the cli - It lists all ecmaScript features available at runTime - Old browser => lib: [“dom”, “es5”] - New browser (or polyfilled) => lib: [“dom”, “esnext”] - Node => lib: [“esX”] (X follows the target version of node) lib / typeRoots / types (1 / 2)

Slide 60

Slide 60 text

- --typeRoots is a list of relative paths to resolve dependencies declarations (default node_modules/@types) - It is available through the cli - No need if dependency handle it’s own definitions - Can be a local directory too - --types is a list of folders names in the typeRoots folder to include during the transpilation - It is available through the cli - Useful to exclude declarations for tests in your code for example lib / typeRoots / types (2 / 2)

Slide 61

Slide 61 text

moduleResolution (1 / 5) - --moduleResolution is a string to configure compiler modules lookup - Two values: “classic” or “node” - Different resolution in case of relative or non relative imports

Slide 62

Slide 62 text

moduleResolution (2 / 5) - “classic” resolution lookup with relative path

Slide 63

Slide 63 text

moduleResolution (3 / 5) - “classic” resolution lookup with non-relative path

Slide 64

Slide 64 text

moduleResolution (4 / 5) - “node” resolution lookup with relative path

Slide 65

Slide 65 text

moduleResolution (5 / 5) - “node” resolution lookup with non-relative path

Slide 66

Slide 66 text

- --baseUrl is a relative path to set the modules root - It is available through the cli - It sets the “/root/” path in the previous examples - Used when a part of the code base is published on a registry - --paths is a map of aliases (non-relative) / relative paths to resolve modules locally - It is not available through the cli - If relative path refers to a ts file, it will be part of the transplication not if it refers to a d.ts file - Same for TypeScript files resolved in the node_modules folder - Do not publish TypeScript files (.ts) on the registry => declarations only baseUrl / paths (1 / 1)

Slide 67

Slide 67 text

- --esModuleInterop is a flag to emit “__importStart” and “__importDefault” helpers (babel compatibility). it activates -- allowSyntheticDefaultImports esModuleInterop / allowSyntheticDefaultImports (1 / 2)

Slide 68

Slide 68 text

- --allowSyntheticDefaultImports is a flag to allow default imports even if declaration has no default export esModuleInterop / allowSyntheticDefaultImports (2 / 2)

Slide 69

Slide 69 text

TypeScript 3.7

Slide 70

Slide 70 text

What’s new in 3.7 : Null Coalescing link - Same as || but don’t treat NaN, 0 and empty string as falsy value.

Slide 71

Slide 71 text

What’s new in 3.7 : Optional Chaining link - Same as && but don’t treat NaN, 0 and empty string as falsy value.

Slide 72

Slide 72 text

What’s new in 3.7 : Recursive Fonction Type Ref link

Slide 73

Slide 73 text

What’s new in 3.7 - Optional Chaining - Nullish Coalescing - Assertion Functions - Better Support for never-Returning Functions - (More) Recursive Type Aliases - --declaration and --allowJs - The useDefineForClassFields Flag and The declare Property Modifier - Build-Free Editing with Project References - Uncalled Function Checks - // @ts-nocheck in TypeScript Files - Semicolon Formatter Option

Slide 74

Slide 74 text

Question?

Slide 75

Slide 75 text

Merci J