TypeScript : Cheat Sheet

TypeScript : Cheat Sheet

What is TypeScript ??

In one line ☝ JavaScript which is scalable === TypeScript

TypeScripts's Type system helps you during the developement (i.e before the codes get compile.) Browsers dont have TS type support.

To compile the TS file

run tsc app.ts in the terminal. If we don't wanna run this command frequently we can run a tsc --init this will create a tscconfig.json file and after that we can compile using tsc command only.

If we also dint want to run the tsc command after the tsc --init command .. We can also use tsc -w or tsc --watch command and it will auto compile the file.

"noEmitOnError": true , in the tsconfig.json file will stop creating files during the compiling if there is any error in the TS

Tips

Basics

function (num: number , str: string , bool: boolean){  //this is how we define number sttring and Boolean
  console.log(num , str , bool);
}


let anyNumber: number = 1 ;  // this is not a good practise

let anyNumber: number;  // this is recommended
anyNumber = 1;

// ALSO

// const is in nature not re-assignable so

const newNum = 9 ; // here newNum is a type of number that is 9

Objects

const owner: {
  name: string; // Key_type pair instead of key_value pair
  age: number; // We can do this but its recommended not to do this
} = {
  name: "Shikhar",
  age: 23,
};

// Let TS do the inference on its own ONLY do inference when the TS is not infering as you want it to be

const owner = {
  name: "Shikhar",
  age: 23,
};

Arrays

const owner = {
  name: "Shikhar",
  age: 23,
  hobbies: ["playing", "biking", "kiting"], //Ts inference will automatically knows its a string[]
};

let activities: string[];
activities = ["abc", "def", "ghi"]; //we can include no number/object/bool in this

// we can also have arrays of object
/*


*/

Tuples

Arrays with a fixed length and having exact types can be called as tuples

const owner: {
  name: string;
  age: number;
  roles: [number, string]; // called tuples (array with fixed length and type orderwise)
} = {
  name: "Shikhar",
  age: 23,
  roles: [69, "vns"],
};

// Only exception in this is that owner.roles.push("newplace") will work (.push method will work)

Enums

To create human readable identifiers we use enums The convention of using enum values all-uppercase but it is not a "mustdo"


enums Role {  //naming start with capital letter
  ADMIN ,
  ATTENDEE,     //here value of ADMIN is 0 , ATTENDEE is 1 and soo on
  AUTHOR
}

// enums Role {  //we can also give enums our own value that we like
//   ADMIN = 2,
//   ATTENDEE,    //Here ADMIN = 2 therefore ATTENDEE = 3 , AUTHOR = 4
//   AUTHOR
// }

// enums Role {  //or we can give all enums its own value
//   ADMIN  = 0,
//   ATTENDEE = "abcd",
//   AUTHOR = true
// }

const owner = {
  name: "Shikhar",
  age: 23,
  role : Role.ADMIN
};

console.log(owner.role) // this will be 0

ANY

Try to avoid using this . Any takes away all the TS features that it provides.

Union Types

Suppose when we want to work with more than 1 type in the function or anywhere else we will use union type

function combine(val: string | number, val2: string | number) {
  // suppose here we want to work with strings and numbers too
  let result;
  if (typeof val === "number" && typeof val2 === "number") {
    return (result = val + val2);
  } else {
    return (result = val.toString() + val2.toString());
  }

  return result;
}

Type Alias

To create a custom type of our own we use the type alias


type NumStr = string | number ; // here we have create a own custom type alias

type OwProp = {            // a custom type
  name: string;
  age: number;
  roles: [number, string];
}

const owner : OwProp = {
  name : "abcd"
  age : 23,
  role : [123 , "xyz"]
}

function combine(val: NumStr , val2: NumStr) {

  let result;
  if (typeof val === "number" && typeof val2 === "number") {
    return (result = val + val2);
  } else {
    return (result = val.toString() + val2.toString());
  }

  return result;
}

Return Function Types

There are two categories of types that can bve returned by the function . The core typeslike Number , String , Boolean and other is :void or :never type .

Ts automatically infers the suggested type after writing the function but we can also explictly ask the function that what it should return

A function with :never will never return anything .

Function as a Type

We can also assign variable a function type

function add(a: number, b: number): number {
  return a + b;
}

// There will be cases when we want a variable to be assign a function

//let combine ; //here combine is :any which is useless
// we want combine to work as add function , we can do that like this

let combine: (x: number, y: number) => number;
// Combine should be any function which takes 2 parameter (that should be number) and
// should return a number

combine = add;

console.log(combine(7, 8));

// we can also use the same pattern {  callbackFunction: (x: number) => void   } to pass
// a function as a callbackFunction (Function that are passed as a arguments)

There is also a : unknown type . It is bit more restrictive than the :any type. We have to do the type-checking in a if(typeof val === "string"){ // do-something} to procede with this

Interface

Interface are like types the key difference between both of them is the familiarity (extends) and declaration merging with OOP of interface is more .

Interfaces can only define objects i.e we CANT use union types in interfaces.

In Interfaces we can extend the properties by implementing it in a another class


interface Greetable {
  name: string;
  greet(n: string): void;
}

// interface Greetable {
         //we can also have a read-only feature if we want a property not to change in future
//   readonly name: string;
//   greet(n: string): void;
// }

class Person implements Greetable {
  // this class should have the the properties of name and greet and it can also have other props of its own
  name : string ,
  age  = 30;     //other special props of Person class

  greet (phrase : string){
    console.log("Hi my name is" + this.name)
  }

  //name and greet are compulsory because they are inherited
}


// INTERFACES CAN ALSO BE EXTENDS

interface Named {
 readonly name: string;

}

interface Greetable2 extends Named {
  greet(n: string): void;
}

// Interface can also be used as a function

interface Add {
  (a: number , b: number) : number
}

// in types we usually do like a arrow

type addFunc = (a: number , b: number) => number;

When we want object to share exact features of it in other classes then we use interfaces .

When you have a preference of choosing the structure of Union , Primitives , Shorthand Functions , Advanced Type Functions use Type instead of interface

Advance TS Features

Intersection types

// When we have two object types that are intersecting its features like this

type Person = {
  address: string;
  name: string;
};

type Employee = {
  name: string;
  job: string[];
};

type ElevatedEmployee = Person & Employee;
// then ElevatedEmployee will have combined feature (properties) of person and employee because {};

//BUT

type Combined = string | number;
type OtherCombine = number | boolean;

type Universal = Combined & OtherCombined; // this will have intersecting feature of number
// Because the number is the type that is common in Combined and OtherCombined

Type Guard

Type-Guard is just use to check where we are getting our desired type or not

//1

if (typeof val === "string") {
  // could be string or number or boolean
}

//2

if ("ObjectPropName" in aObject) {
  // do something if the objectPropName property is present in the "aObject"
}

//3

if (parameterIs instanceof aClassObj) {
  //proceede with the code
}

// We can TypeCast a element using a `as` syntax

ex: (document.querySelector("p") as HTMLInputElement).value = "Hello Bhai";

Generic Types

When the value is unknown and you are expecting a particular type to take out of the info recieved then you can use generic types

Mainly used on Arrays and Promise

const result: Array<string> = [];
const result2: Array<string | number> = [];

const somePromise: Promise<string> = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("I am a String");
    // if the resolve here will be number or boolean then we will get err while using .then method
  }, 2000);
});

somePromise.then((data) => {
  data.split(" "); // this will give err if resolve is not the desired type
});

And that's all for this blog .

More advance topics will be covered in the future blogs.