1. Create a type checking function

interface IDog{
   name:  string;
   age: number;
   kidFriendly: boolean;
}

interface ICat{
   name: string;
   age: number;
   activityLevel: number;
}

type Animal = IDog | ICat;

/** Is the animal a dog ? */
const isDog = (animal: Animal) : animal is IDog => (animal as IDog).kidFriendly !== undefined;

if(isDog(animal)){
   console.log(animal.kidFriendly);
}

2. Set all properties of an interface to optional

interface IDog{
   name: string;
   age: number;
   kidFriendly: boolean;
}

const dog : Partial<IDog> = {
   name: "Rex"
}

3. Get the type of the parameters of a function

const walkDog = (dogName: string, distance: number) => { /** ... */ }

const params: Parameters<typeof walkDog> = ["Rex", 48];

4. Use Setters and Getters

Setters and Getters also exist in plain JavaScript. Still, they are very useful in TypeScript (and other languages).

class Dog{
   private _name: string = "";

   get name(): string{
      return this._name;
   }

   /** Check the length of the name before setting it **/
   set name(newName: string){
      if(newName.length < 8) {
         throw new Error(`The dog's name needs at least 8 charachters`)
      }

      this._name = newName;
   }
}

5. Optional chaining

Optional chaining has recently been added to JavaScript (ECMAScript 2020).

let cat?: ICat;  

/** With optional chaining **/
let animal = cat?.fur.length;

/** Without optional chaining **/
let cat = cat === null || cat === undefined ? undefined : car.fur.length;