Skip to main content

07-02-misunderstanding-typescript-compilation

  • For TypeScript, please give 15 key points, tips and tricks I should know for a job interview about Misunderstanding TypeScript Compilation

Misunderstanding TypeScript Compilation:

Sure, I'll provide explanations and corresponding TypeScript code examples for each key point you've listed.

JavaScript Superset:

TypeScript is built on top of JavaScript. This means you can use all JavaScript features, and they will work just the same in TypeScript. When TypeScript is compiled, it turns into JavaScript that can run anywhere JavaScript runs.

  • Code Example:

    // Valid JavaScript code
    const message = "Hello, JavaScript!";
    console.log(message); // This will log "Hello, JavaScript!"

    // Also valid TypeScript code
    const greeting: string = "Hello, TypeScript!";
    console.log(greeting); // This will log "Hello, TypeScript!"

Not a Guarantee for Runtime Errors:

Even if TypeScript code compiles without any errors, it does not mean the code will run perfectly. TypeScript checks for errors before the code runs, but some errors can only happen during execution, which TypeScript cannot predict.

  • Code Example:

    // This TypeScript compiles fine
    function addNumbers(a: number, b: number) {
    return a + b;
    }

    // But this will cause a runtime error
    console.log(addNumbers(5, null)); // This can throw an error if not handled properly

Type Erasure:

TypeScript types are there to help during development. When TypeScript is compiled to JavaScript, all type annotations are removed. This means that type checking does not happen at runtime.

  • Code Example:

    // TypeScript with type annotations
    let age: number = 25;

    // Compiled JavaScript output, type annotations are removed
    let age = 25;

No Performance Optimization:

TypeScript focuses on improving the development process by adding types to JavaScript. It does not make the JavaScript code run faster or more efficiently.

  • Code Example:

    // TypeScript code with type annotations
    function calculateDistance(speed: number, time: number): number {
    return speed * time;
    }

    // Compiled JavaScript code is the same in logic, no performance optimization is done
    function calculateDistance(speed, time) {
    return speed * time;
    }

TypeScript Targets:

The target in tsconfig.json tells TypeScript what version of JavaScript it should produce. This allows you to use newer JavaScript features in TypeScript and compile them down to a version that your target environments can understand.

  • Code Example:
    // tsconfig.json
    {
    "compilerOptions": {
    "target": "es5" // Compiles down to ES5 compatible JavaScript
    }
    }

Module Systems:

TypeScript can output different JavaScript module systems based on your project needs, which can be specified in the module option of tsconfig.json. This means you can write modules in TypeScript and compile them to the module system of your choice.

  • Code Example:
    // tsconfig.json
    {
    "compilerOptions": {
    "module": "commonjs" // Compiles TypeScript modules to CommonJS modules
    }
    }

Strictness Options:

TypeScript has strictness settings that you can enable or disable. These settings make TypeScript check your code more or less strictly. For example, strictNullChecks makes sure you do not accidentally use a value that could be null or undefined.

  • Code Example:
    // tsconfig.json
    {
    "compilerOptions": {
    "strictNullChecks": true, // Do not allow 'null' or 'undefined' to be assigned to any variable
    "noImplicitAny": true // Do not allow variables to have an 'any' type implicitly
    }
    }
    Type Compatibility:

TypeScript's type system checks for compatibility based on the shape of the types, which is why it's called structural typing. This means that two objects are considered compatible if they have the same shape, even if they are not instances of the same class.

  • Code Example:

    interface Point {
    x: number;
    y: number;
    }

    class Point2D {
    constructor(public x: number, public y: number) {}
    }

    // Even though 'Point2D' is not explicitly declared to implement 'Point',
    // they are structurally compatible.
    let point: Point = new Point2D(1, 2);

Ambient Declarations:

When working with existing JavaScript code or libraries, you can use the declare keyword to tell TypeScript that a certain variable, module, or type exists.

  • Code Example:
    // Ambient declaration for a library or variable that exists elsewhere
    declare var myOldJavaScriptLibrary: any;

Triple-slash Directives:

Triple-slash directives are single-line comments containing a single XML tag. They are used to give instructions to the compiler and should be placed at the top of the file.

  • Code Example:
    /// <reference path="..."/>
    // This directive tells the compiler to include another file in the compilation process.

Declaration Merging:

TypeScript allows for merging multiple declarations with the same name into one. This is useful for extending existing types or interfaces.

  • Code Example:

    interface Box {
    height: number;
    }

    interface Box {
    width: number;
    }

    // TypeScript merges both declarations into one
    let box: Box = { height: 10, width: 20 };

Transpiler vs Compiler:

TypeScript is sometimes called a transpiler because it converts TypeScript code to JavaScript, which is at a similar abstraction level, rather than compiling it to a lower-level language.

  • Code Example:

    // TypeScript
    const greeting: string = "Hello, World!";

    // Transpiled JavaScript
    const greeting = "Hello, World!";

Source Maps:

By setting "sourceMap": true in tsconfig.json, TypeScript generates source maps that map the compiled JavaScript back to your original TypeScript code, which is very helpful for debugging.

  • Code Example:
    // tsconfig.json
    {
    "compilerOptions": {
    "sourceMap": true
    }
    }

Type Assertions:

Type assertions are a way to tell the TypeScript compiler that you know more about the type of a variable than it does. However, misuse of type assertions can lead to problems since you're overriding TypeScript's type checks.

  • Code Example:

    // The compiler does not have enough information to infer the type
    let someValue: any = "This is a string";

    // Type assertion allows you to specify a more specific type
    let strLength: number = (someValue as string).length;

Declaration Files:

Declaration files (.d.ts) in TypeScript are used to describe the shape of an existing JavaScript codebase to TypeScript, without providing the implementation.

  • Code Example:
    // Declaration file for a JavaScript library
    // file: myLibrary.d.ts
    declare module "myLibrary" {
    export function doSomething(): void;
    }

These examples showcase how each TypeScript feature works and demonstrate their practical application in code.