Structural Typing

Type script is structurally typed, and therefore has some strange rules when dealing with interfaces and objects

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

interface Vector3D {
    x: number;
    y: number;
    z: number;
  }

  function calculateLength(v: Vector2D): number {
    return Math.sqrt(v.x * v.x + v.y * v.y)
  }

  function normalize(v: Vector3D): Vector3D {
    let length = calculateLength;
    return {
        x: v.x / length,
        y: v.y / length,
        z: v.z / length,
    }
  }

In this example no errors are thrown, even though in normalize() a 3D vector is getting passed to a 2D vector. This works because its structure was compatible, that is, both interfaces had an x and y and typescript checks the stucture of the types, rather than their names (as in the case with nominal type systems i.e. C++)

Typescript also makes assumptions about objects. Take this for example.

  function normalize(v: Vector3D): Vector3D {
    let length = calculateLength(v);
    for (const axis of Object.keys(v)){
      const coord = v[axis] // error
      length += coord
    }
    return length;
  }

This will return an error that says coord has any type for 2 reasons. 1. because there could be any properties on the object, not necessarily just numbers 2. [axis] (the key) hasn't been given a type of string.

interface Vector3D {
  [key: string]: number;
  x: number;
  y: number;
  z: number;
}

This locks the key with the type of string, which allows you to use it to index the object, and it locks the value as a number.

  class C {
    foo: string;
    constructor(foo: string) {
      this.foo = foo;
    }
  }

  const c = new C('instance of C');
  const d: C = {foo: 'object literal'};

Because typescript is structurally typed, const d is permitted to be of type C, due to the fact that the foo property is present with a string as the value.

The any type

There are language services for interfaces and types, autocomplete and tsserver are a nice combo.

Avoid any whenever you can, it minimizes the value that typescript provides.