Mastering TypeScript Fundamentals

Mastering TypeScript Fundamentals

TypeScript empowers JavaScript with static typing, enhancing development productivity and code reliability

What is typescript?

TypeScript is a programming language that builds upon JavaScript and brings additional features. It introduces static type checking, which means it checks the types of values you're using in your code to catch mistakes early on. As you write your code, TypeScript analyzes it in real time, providing feedback and ensuring you use the correct types effectively. It's like having a helpful friend who analyzes your code as you type, making your coding experience easier and more organized.

Types in typescript

TypeScript has a variety of built-in types that you can use to define your variables. Here are some of the most common ones:

  • number: represents numeric values like 42 or 3.14

  • string: represents text values like "Hello, world!" or "42"

  • boolean: represents boolean values true or false

  • null and undefined: represents the absence of a value

  • object: represents any object type, including arrays and functions

  • any: represents any type, and can be used when you don't know the type of a variable ahead of time

  • void: represents the absence of a value, typically used as a return type for functions that don't return anything

In addition to these basic types, TypeScript also supports more advanced types like union types, intersection types, and generics. But more on these later.

Syntax: let variableName: type = value

let num: number = 67

Type Inference

Type inference in TypeScript is like having a clever assistant who can automatically guess and figure out the types of values in your code based on how you use them. It saves you from explicitly declaring types every time, making your code more concise and readable. With type inference, TypeScript analyzes your code and infers the types behind the scenes, making programming faster and more intuitive.

eg: let num = 7

The type of num will automatically be inferred as a number.

In case ts is not able to infer the type, it will set it as any.

To prevent the above scenario from happening we can use noImplicitAny in our config file. As any isn't type-checked, we should avoid using it.

Defining Functions

Defining parameter types:

cont funcName = ( var1: type, var2: type) => {}

Defining return type:

cont funcName = (): type => {}

Example: A function taking in the date and returning the number of days from that date

const getDaysFromDate = (date: Date): number => {
  const today: Date = new Date();
  const timeDifference: number = today.getTime() - date.getTime();
  const daysDifference: number = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
  return daysDifference;
}

Type Alias

A type alias in TypeScript is like giving a nickname to a specific type. It allows you to create a custom name for a type, making your code more expressive and readable. Instead of repeatedly using complex or lengthy type annotations, you can define a type alias once and then use that alias throughout your code.

Eg: you can create a type alias, userD, which you can use anywhere you want to perform any operation on the user.

type UserD = {
    name: string;
    age: number;
}

const updateUser = (user: UserD) => {
    // some code
}

Readonly

The readonly modifier in TypeScript is used to indicate that a property of a type can only be read and cannot be modified. It ensures that once a property is assigned a value, it cannot be changed later.

type UserD = {
    readonly _id: string;
    name: string;
}

Typescript will throw an error if we try to change the value of the _id.

Combining types

type A = { name: string }

type B = A & { isPro: boolean }

now B becomes: { name: string; isPro: boolean }

Defining Arrays

type[] and Array<type>

These are functionally equivalent and can be used interchangeably. The choice between them often comes down to personal preference or the existing coding style within a project.

const arrName: type[] = []

const arrName: Array<type> = []

Specifying length:

We can specify the length an array is supposed to be, if you try to add or remove values from the array, TypeScript will give you an error because it doesn't match the defined length.

const arrName: Array<type, length> = []

ReadonlyArray:

ReadonlyArray type is a built-in utility type that represents an immutable array. It ensures that the array cannot be modified once it is created, preventing any additions, removals, or modifications to its elements.

The ReadonlyArray type is useful when you want to create arrays that should remain constant and not be modified inadvertently.

const arrName: ReadonlyArray<type> = []

A good use case of type aliases can be defining a type of userD for an array of users.

type UserD = {
    id: number;
    name: string;
    age: number;
}

const users: UserD[] = [
    {id: 1, name: 'Mario', age: 20},
    {id: 2, name: 'Luigi', age: 23}
]

Unions

A union in TypeScript is like a combination of different types. It allows you to define a type that can be one of several types. For example, you could have a variable that can be either a number or a string. The types are separated by pipe | symbol.

type id = number | string

type arr = (boolean | string)[]

Tuples

A tuple is an array type that knows exactly how many elements it contains and exactly which types it contains at specific positions.

syntax: type tupleName = [string, number]

eg: let arr: [string, boolean];

if we define arr like this: arr = [23, false] it will throw an error as type of element on index 0 should be a string, not a number.

type Person = [string, number, boolean]

const person: Person = ["John Doe", 30, true]

Interface

The interface is the same as the type alias but with a few additional features:

  1. It can be re-opened i.e., we can redefine the interface with some additional properties. E.g.

      interface UserD { 
         name: string;
         age: number;
      }
    
     interface UserD {
         isPro: boolean;
     }
    

    Re-opening interface does not override the previous definition. But it adds the new types with the previous ones. So now UserD contains name, age and isPro.

  2. Can extend other interfaces. E.g.

     interface Animal {
       name: string;
       age: number;
       sound(): void;
     }
    
     interface Dog extends Animal {
       breed: string;
       bark(): void;
     }
    

Be careful while naming interfaces, as you might be re-opening some interface present in a file of some library that you downloaded.

Enum

It allows you to define a set of named constants. It helps us define a specific list of options or choices that something can be. For example, if we have a system with three user roles: "Admin", "Moderator", and "User". Instead of using plain strings to represent these roles throughout the code, we can define an enum called "UserRole" with these three members.

enum UserRole {
  Admin = "ADMIN",
  Moderator = "MODERATOR",
  User = "USER"
}

That concludes this blog, you now possess the essential knowledge to seamlessly incorporate TypeScript into your projects. Best of luck on your path to becoming an exceptional software developer, and may your web creations be nothing short of extraordinary!