Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

[email protected]

November 13, 2019
Tweet

Other Decks in Programming

Transcript

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

    View Slide

  2. Paris TypeScript

    View Slide

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

    View Slide

  4. Part 1: Let’s get started

    View Slide

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

    View Slide

  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!";

    View Slide

  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;

    View Slide

  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

    View Slide

  9. How it works?

    View Slide

  10. Some features

    View Slide

  11. 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);
    }
    }

    View Slide

  12. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. Demo

    View Slide

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

    View Slide

  18. Question?

    View Slide

  19. Merci J

    View Slide

  20. Part 2: TypeScript beyond the basics

    View Slide

  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

    View Slide

  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

    View Slide

  23. Advanced Types

    View Slide

  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

    View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  41. Strict mode

    View Slide

  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

    View Slide

  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 :

    View Slide

  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

    View Slide

  45. --strictNullChecks (2/4) link
    - Exemple

    View Slide

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

    View Slide

  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.

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  53. Compiler

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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)

    View Slide

  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)

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

  69. TypeScript 3.7

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  74. Question?

    View Slide

  75. Merci J

    View Slide