Microsoft Ignite The Tour Paris - A TypeScript journey!

Microsoft Ignite The Tour Paris - A TypeScript journey!

Presentation on TypeScript made with Félix Billon, Paul Souche and Terance Moussoki

9298dcce5b2b0e88d8ffbb837192ca98?s=128

Sylvain Pontoreau

November 13, 2019
Tweet

Transcript

  1. A TypeScript journey Microsoft Ignite The Tour - Paris 2019

    Sylvain Pontoreau Terance Moussoki Paul Souche Félix Billon
  2. Paris TypeScript

  3. @ParisTypeScript Who we are and how to contact us @spontoreau

    @MoussokiT @lsagetlethias @felix_billon @paulsouche
  4. Part 1: Let’s get started

  5. What's the problem with JavaScript? Let's take a look on

    some code!
  6. 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!";
  7. 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;
  8. 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
  9. How it works?

  10. Some features

  11. Generic An exemple with the Factory pattern: abstract class Rocket

    { constructor( public readonly boosters : number ) { } 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); } }
  12. Generic Generic & type system: // type alias type Rocket

    = { id: number; model: string; boosters: number; }; // Mapped type type Partial<T> = { [K in keyof T]?: T[K]; }; const e: Partial<Rocket> = { }; // Conditional type Exclude<T, U> = T extends U ? never: T; type Keys = Exclude<keyof Rocket, "id">; You will have more information about that in Part 2
  13. Decorators Currently experimental! Can be apply on: • Classes •

    Methods • Properties • Parameters TC 39: Draft "experimentalDecorators": true, "emitDecoratorMetadata": true,
  14. 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; };
  15. 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));
  16. Demo

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

  18. Question?

  19. Merci J

  20. Part 2: TypeScript beyond the basics

  21. 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
  22. 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
  23. Advanced Types

  24. 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
  25. 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)
  26. Never / unknown / type alias / as const (3

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

    / 4) link Cast as const returns a readonly literal type
  28. 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)
  29. Literal / index types (2 / 2) link With index

    types the compiler checks code that use dynamic property names
  30. Union / Intersection (1 / 2) link An union type

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

    is actually the “union” of its members
  32. 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
  33. Type Guards (2 / 3) link Most of the time

    we use it with a literal type
  34. Type Guards (3 / 3) link And if not an

    union type
  35. Mapped / Conditional types (1 / 6) link A mapped

    type is a “function type” that takes a type and map it thanks to indexable types
  36. Mapped / Conditional types (2 / 6) link Very powerful

    to transform types
  37. Mapped / Conditional types (3 / 6) link A conditional

    type selects one of two possible types based on a condition
  38. Mapped / Conditional types (4 / 6) link Unleash power

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

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

    of both
  41. Strict mode

  42. 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
  43. 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 :
  44. --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
  45. --strictNullChecks (2/4) link - Exemple

  46. --strictNullChecks (3/4) - To handle null and undefined you can

    use : - Union type : link - Type Guard : link
  47. --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.
  48. --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
  49. --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
  50. --noImplicitThis (2/2) link - You can enforce the type of

    this by typings it as a first argument in a function
  51. --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
  52. --strictPropertyInitialisation (2/2) link - In some specific case you can

    use definite assignment assertion operator “!”
  53. Compiler

  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. - --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)
  60. - --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)
  61. 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
  62. moduleResolution (2 / 5) - “classic” resolution lookup with relative

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

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

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

    path
  66. - --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)
  67. - --esModuleInterop is a flag to emit “__importStart” and “__importDefault”

    helpers (babel compatibility). it activates -- allowSyntheticDefaultImports esModuleInterop / allowSyntheticDefaultImports (1 / 2)
  68. - --allowSyntheticDefaultImports is a flag to allow default imports even

    if declaration has no default export esModuleInterop / allowSyntheticDefaultImports (2 / 2)
  69. TypeScript 3.7

  70. What’s new in 3.7 : Null Coalescing link - Same

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

    as && but don’t treat NaN, 0 and empty string as falsy value.
  72. What’s new in 3.7 : Recursive Fonction Type Ref link

  73. 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
  74. Question?

  75. Merci J