TypeScript - robbiehume/CS-Notes GitHub Wiki

Links:

Overview

Compiling / running:

  • tsc: used to compile .ts file to a .js file
  • ts-node: used to run TypeScript code for backend
  • There is a 'types' repo that is open source and contains useful type documentation for certain classes / packages that aren't documented
  • Can opt-out of the type system by using any annotation

tsconfig.json

  • The tsc compiler will automatically look for this file
  • {
      "compilerOptions": {
        "target": "esnext", // choose which es version to compile to; defaults to es3
        "watch": true,  // automatically re-compile when ts file is saved
        "lib": ["dom"]  // include typings for certain environments; the Dom allows TS to compile your code with all the native DOM classes 
      }
    } 
    

General Notes

Function parameter type adherence

  • const showProduct = (name: string, price:number)  => {
      console.log(`The product ${name} costs $${price}.`);
    };
    

Types

  • In TypeScript (TS), a type is a convenient way to refer to the different properties and functions that a value has
  • A value is anything that you can assign to a variable e.g., a number, string, array, object, function, etc.
  • Primitive types in JS/TS: string, number, boolean, null, undefined, symbol
  • Object types: functions, arrays, classes, etc.
  • You can also create your own types

Understanding Type Annotations

  • TS uses type annotations to explicity specify types for identifiers such as variables, functions, objects, etc
  • TS uses the syntax : type after an identifier as the type annotation, which type can be any valid type
  • Once an identifier is annotated with a type, it can be used as that type only
  • Example:
    let tmp: string;
    let name: string = 'John';
    let age: number = 25;
    let active: boolean = true;
    
  • Type annotation examples:
    • To annotate an array type you use a specific type followed by a square bracket : type[]

      let arrayName: type[];
      let names: string[] = ['John', 'Jane', 'Peter', 'David', 'Mary'];
      
    • To specify a type for an object, you use the object type annotation

    • In this example, the person variable only accepts an object that has two properties

      let person: {
        name: string;
        age: number };
      
      person = {
        name: 'John',
        age: 25
      }; // valid
      

Function arguments & return types

  • The following shows a function annotation with parameter type annotation and return type annotation:
    • let greeting : (name: string) => string;
  • In this example, you can assign any function that accepts a string and returns a string to the greeting variable:
    • greeting = function (name: string) {
        return `Hi ${name}`;
      };
      
  • Function definition example:
    • function pow(x: number, y: number): number {
        return Math.pow(x, y)
      }
      pow(5, 2)  // works
      pow(5, '2')  // doesn't work 
      
  • Can set the return type to void if it doesn't return anything

Arrays

  • const arr: number[] = []  // only allow numbers to be added 
    arr.push(1)  // works
    arr.push('2')  // doesn't work 
    
  • Can also restring the array type to a

Interfaces

  • Interfaces allow you to enforce the 'shape' of an object by defining the properties and types the properties can have
  • Ex:
    interface Product{
      id: number,
      name: string,
      price: number
    };
    
  • Can also add [key: string]: any to the interface list to allow any other attributes

TypeScript Type Inference

Basic type inference

  • Type inference describes where and how TS infers types when you don't explicitly annotate them
  • If you initialize a variable with a number, it will infer that the type is number:
    • let counter = 0; is equivalent to let counter: number = 0;
  • Likewise, when you assign a function parameter a value, TS infers the type of the parameter to the type of the default value
    • In this example, TS infers the type of the max parameter to be number
      function setCounter(max=100) {
        ...
      }
      
  • Similarly, TS infers the following return type of the increment() function as number:
    • function increment(counter: number) {
        return counter++;
      }
      // is the same as: 
      function increment(counter: number) : number {
        return counter++;
      }
      

The best common type algorithm

  • Consider the following assignment: let items = [1, 2, 3, null];
  • To infer the type of the items variable, TS needs to consider the type of each element in the array
  • It uses the best common type algorithm to analyze each candidate type and select the type that is compatible with all other candidates
  • In this case, TS selects the number array type (number[]) as the best common type
  • If you add a string to the items array, TypeScript will infer the type for the items as an array of numbers and strings: (number | string)[]

Type inference vs Type annotations

  • Type inference: TS guess the type; Type annotations: you explicitly tell TS the type
  • In practice, you should always use the type inference as much as possible and use the type annotation in the following cases:
    • When you declare a variable and assign it a value later
    • When you want a variable that can’t be inferred
    • When a function returns the any type and you need to clarify the value