TypeScript 101: The Basics You Need to Know

Nidhin MNidhin M
14 min read

Introduction: Discovering the Magic of TypeScript

Hey there, folks! In this blog, we're diving into TypeScript, a cool tool for developers. If you know a bit about JavaScript, you might have heard about TypeScript – it's like a sibling to JavaScript. Don't worry if you're new – we'll make it easy for you to understand.

So, What's TypeScript? At its core, TypeScript is like a special friend for developers who want to write better code. It's like giving your code superpowers! Imagine if your code could catch mistakes before they cause problems – TypeScript helps with that.

Think of it like building a sandcastle on the beach – you want it to stay strong and not fall apart. TypeScript is like using better tools and instructions to build your sandcastle so it lasts longer and doesn't collapse.

But remember, it's not magic. It won't make all problems disappear. TypeScript helps by showing you where problems might happen, so you can fix them before they turn into big issues.

If you're curious about why people are excited about TypeScript, stick around! We're going to learn about TypeScript simply. No complicated jargon – just the good stuff. We'll figure out what TypeScript is, why it's cool, and how it can make your coding adventures smoother.

Ready for this TypeScript journey? Let's get started!

Starting Out with TypeScript

Before we dive into the basics of TypeScript, it's important to set up the right environment on your system. Follow these steps to get started:

1. Install Node.js:

Before working with TypeScript, make sure you have Node.js installed on your system. If you don't have it, you can download and install it from the official Node.js website (https://nodejs.org/). If you already have Node.js installed, ensure that you have a reasonably recent version.

2. Check Node.js Version:

Open your command line or terminal and enter the following command to check your Node.js version:

node -v

This will display the version number. TypeScript requires Node.js, so having it up-to-date is important.

3. Install TypeScript Globally:

To use TypeScript across your system, you can install it globally. Open your command line or terminal and use the following command to install TypeScript:

npm install -g typescript

This installs TypeScript globally, making it accessible from any directory in your system.

4. Check TypeScript Version:

After installing TypeScript, you can check its version by running the following command:

tsc -v

This will display the installed version of TypeScript.

Now you're all set up to start your TypeScript journey! With the environment ready, we can move on to exploring the basics of TypeScript.

Getting to Know TypeScript Data Types

Awesome! You're about to dive into TypeScript, and we'll start by exploring some common data types in a simple way.

Primitive Data Types

Think of data types as labels for your variables, telling TypeScript what kind of stuff they hold.

  • string - This type signifies that a variable will store string values.
let isString: string = "It's a string";
  • number - It indicates that a variable will store numeric values.
let isNumber: number = 5;
  • boolean - This type represents variables that store Boolean values.

      let isBoolean: boolean = true;
    

    A quick tip:Always use lowercase for types. Uppercase types are typically reserved for built-in types, which are rarely used.

  • Arrays

    Next up, arrays. In TypeScript, you can declare that a variable will store an array of a particular type. For instance, if you intend to store numbers in an array:

let numArray: number[];

The same principle applies to strings, booleans, and even objects.

  • any Type

Now, let's talk about any type. It's like a wildcard, allowing you to use any type without TypeScript's strict checking. Be cautious with any , since it can make your code less type-safe. It's best to use it only when necessary:

let anything: any = "hi";

anything = 5;
anything = true;

Mastering TypeScript Functions: A Hands-On Guide

We've already explored the wonders of TypeScript and got familiar with data types. Now, it's time to get cosy with functions. Think of functions as your code's helpers – they do tasks for you. In this section, we'll play around with real-life examples to see how TypeScript makes them even better.

Ready? Let's roll!

Adding Two Numbers

Our first function, addTwo, takes a number as input and returns the input value plus 2. TypeScript ensures that this function works with numbers and returns a number.

function addTwo(num: number): number {
  return num + 2;
};

It's a function that takes a string as input and returns a number. In TypeScript, we can specify the types of functions too. It's like telling TypeScript the rules a function should follow.

Uppercasing a String

Next up, getUpper is a function that takes a string and returns its uppercase version. TypeScript helps us work with strings and ensures type safety.

function getUpper(val: string): string {
  return val.toUpperCase();
};

User Signup

The signUpUser the function is more complex. It takes in a name (string), an email (string), and a boolean flag for payment status (boolean). It logs a greeting message to the console with the input name. It doesn't return anything so we can keep the function return type as void

function signUpUser(name: string, email: string, isPaid: boolean): void {
  console.log(` Hi ${name}`);
};

User Login

loginUser is another function, but it has a default parameter. It takes a name (string) and an optional boolean flag for payment status. TypeScript allows us to specify default values.

// Arrow Function
let loginUser = (name: string, isPaid: boolean = false): void => {};

Error Handling

Lastly, TypeScript assists us in error handling. We define functions to log and throw errors with specific types.

function consoleError(errMsg: string): void {
  console.log(errMsg);
};

function handleError(errMsg: string): never {
  throw new Error(errMsg);
};

In the first function takes a string called errMsg as its parameter. Its purpose is to log error messages to the console. The : void part means that this function doesn't return any value; it just logs the error.

In the second function is used when something goes seriously wrong in your code. It also takes an errMsg parameter, which is a string describing the error. The : never indicates that this function never returns a value; instead, it throws an error with the specified error message. It's a way to signal that an unrecoverable error has occurred.

Managing Data: Your Guide to TypeScript Objects

Imagine data as pieces of a puzzle. TypeScript's object handling acts like a box that keeps all the pieces organized. It's like having separate compartments for every piece, making the puzzle easier to solve. Let's unlock the treasure chest of TypeScript objects and see how they simplify your data management.

Creating Order with Type Aliases

Before we dive into the exciting world of TypeScript objects, let's understand the magic of type aliases. Type aliases serve as customized shortcuts for complex type definitions, making your code more concise and readable. Instead of repeatedly typing out intricate structures, you can use type aliases to condense them into simpler, more manageable forms. Consider this example:

type User = {
  readonly _id?: string; // _id is set as readonly, meaning it cannot be mutated, the "?" mean that it is optional
  name: string;
  email: string;
  isActive: boolean;
};

type Mystring = string;

By using type aliases, you simplify the representation of intricate types, making your code more comprehensible and easier to maintain.

Playing with Object Properties

Now, let's venture into the realm of TypeScript objects and their versatile properties. With objects, you can manage data more effectively, creating and manipulating structured information effortlessly. Let's explore how TypeScript empowers you to handle objects seamlessly:

// Utilize the User type in the following function
let newUser = { name: "hitesh", isPaid: false, email: "A@fgmail" };

// Create a function, leveraging the User type for enhanced data management
function createUser(user: User): User {
  // Return a new user object
  return { 
    name: user.name, 
    email: user.email, 
    isActive: true 
  };
}

Using the User type ensures that the createUser function aligns with the defined structure, facilitating smooth data management and manipulation within TypeScript.

Unlocking Advanced Object Management in TypeScript

In TypeScript, mastering intersection types enables you to efficiently combine various data structures, empowering you to handle complex data effortlessly. Here's a quick brief look:

type cardNumber = {
  cardnumber: string;
};

type cardDate = {
  cardDate: string;
};

type cardDetails = cardNumber & cardDate & {
  cvv: number;
};

Embracing Arrays: Your Data Powerhouse

Let's talk about arrays in TypeScript. Consider arrays as convenient shelves where you can store and access your items effortlessly. They help us maintain our data in an organized manner.

Creating Arrays

To start, let's create an empty array to hold the names of our beloved superheroes:

const superHeroes: string[] = ["batman", "superman", "spiderman"];
//superHeroes is an array of strings

We can also create an array to store the power levels of our heroes:

const heroPower: number[] = [10, 8, 8];
//heroPower is an array of numbers

Playing with Fancy Data

By using custom types, like our 'User' type below, we can manage more complicated data. Think of it like having special cards for your favourite superheroes, including their powers and secret identities:

type User = {
  name: string;
  isActive: boolean;
};

const allUsers: User[] = []; // Our special array for user objects

Handling Big Stuff

Arrays can even hold other arrays, making them perfect for holding more complex data structures. It's like having special compartments in your shelf where you can store your kinds of stuff

const MLModels: number[][] = [
  [255, 255, 5343], // An array containing three numbers
  [8, 43], // An array containing two numbers
];

Adding Fun Stuff

Adding new stuff to arrays is simple. we can push the method by which will do the work for us.

allUsers.push({ name: "", isActive: true }); // Adding a new hero to our user collection
superHeroes.push("nidhin"); // Adding a new superhero's name
heroPower.push(4); // Adding a power level to our hero

Arrays are awesome for keeping all your data neatly organized. With TypeScript, managing and sorting your data becomes a piece of cake!

Understanding Union Types , Tuples and Enums in TypeScript

Indeed, TypeScript enhances code robustness by enforcing type safety, compelling developers to follow specific data types. While the 'any' type offers unparalleled flexibility, it relaxes TypeScript's stringent type-checking. However, there are scenarios where striking a balance between type safety and flexibility is paramount.

Union Types

Union types seamlessly combine the robustness of TypeScript's strict typing with the necessary flexibility for effective data management and manipulation.

Let's understand union types with some examples, so you can use this feature in your next project.

let score: number | string = 33;

score = 44;
score = "34";

In the given code, the variable 'score' can be either a string or a number. This approach provides flexibility without compromising TypeScript's strictness.

Here is another example using types:

// Defining types 'User' and 'Admin' with respective properties
type User = {
    name: string;
    id: number;
};

type Admin = {
    username: string;
    id: number;
};

// Declaring a variable 'nidhin' with the type 'User' or 'Admin' union
let nidhin: User | Admin = {
    name: "midhum", // Assigning a name to the 'nidhin' object
    id: 4, 
};

// Reassigning 'nidhin' as an 'Admin' type object
nidhin = {
    username: "nid", // Changing the username property for the 'nidhin' object
    id: 4,
};

For instance, 'nidhin' can hold values that conform to either the 'User' or 'Admin' type. This flexibility enables smoother handling of diverse data structures, making your code adaptable and concise.

These examples demonstrate how union types can be used to manage different data types effectively, allowing for increased flexibility while ensuring type safety.

Tuples

Tuples in TypeScript act like strict teachers. Unlike union types, they make us fully follow TypeScript's rules. They help represent arrays with fixed lengths and specific data types, making sure we manage data in a disciplined way.

let tUser: [string, number, boolean];
// This line declares a variable 'tUser' as a tuple that can contain three elements:
tUser = ["hc", 4, true];
// This line assigns a value to 'tUser' where the first element is "hc", the second element is 4, and the third element is true.
tUser = ["hc", 4, 8];//ERROR
//Type 'number' is not assignable to type 'boolean'.

tuples in TypeScript have fixed lengths, which means you can't push new values into them once they're defined. This rigidity ensures that the structure of the tuple remains consistent and predictable throughout the code.

Enums

Enums provide a helpful way to create a group of named constants, making your code easier to understand and manage. In this way Enums help us to write more readable and maintainable code. Let's see some of examples in which enums are used

  1. Numeric enums

    In Numeric enums, by default, the first member will get initialized at 0 like in Arrays and others will get auto-incremented.

    In the given example we have intialized Up with 1 , so other members will get increment to 2,3,4

enum Direction {
  Up = 1,
  Down,
  Left,
  Right,
}
  1. String enums

    In a string enum, each member has to be constant-initialized with a string literal.

enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

Interfaces in TypeScript

Interfaces in TypeScript define the structure of our objects, ensuring that they adhere to specific properties and methods.

Let's look at how we can create an interface and how to use it.

interface User {
  readonly dbId: number; // Represents a unique database identifier for the user (read-only)
  email: string; // Represents the user's email address
  userId: number; // Represents the user's ID
  googleId?: string; // Represents the user's Google ID (optional)
  startTrail(): string; // Represents a function to start a trial and returns a string
  getCoupon(couponName: string): number; // Represents a function to get a coupon by name and returns a number
}

In the above code snippet, we have defined an interface using various properties specific to TypeScript, like readonly and optional.

We can also extend the interface to add more properties:

interface User {
  gitHubId: string; // Represents the user's GitHub ID
}

Using the User interface, we can now create a user object.

const nidhin: User = {
  dbId: 4, // Unique database identifier
  email: "nidn@ga", // Email address
  userId: 4, // User ID
  startTrail: () => {
    return "Trial started!"; // Implementation of startTrail method
  },
  getCoupon: (name: "SUMMER21") => {
    return 10; // Implementation of getCoupon method
  },
};

With the User interface, we can create another interface that includes all the properties of User and adds extra properties specific to an admin user. Let's see how we can create an admin user interface.

Extending the User Interface to Create an Admin Interface

We can extend the User interface to include additional properties and methods for an admin user. This allows us to reuse the properties of the User interface while adding new ones specific to the admin.

// Extending the User interface to create an Admin interface
interface Admin extends User {
  role: "admin" | "ta" | "learner"; // Represents the role of the admin, which can be "admin", "ta", or "learner"
}

With the Admin interface in place, we can create an admin object. This object will have all the properties and methods defined in the User interface, along with the additional role property specific to the admin.

const nidhinAdmin: Admin = {
  dbId: 4, // Unique database identifier
  gitHubId: "ba", // GitHub ID
  email: "nidn@ga", // Email address
  userId: 4, // User ID
  role: "admin", // Role of the admin user
  startTrail: () => {
    return "Admin trial started!"; // Implementation of startTrail method
  },
  getCoupon: (name: "SUMMER21") => {
    return 15; // Implementation of getCoupon method
  },
};

In this example, we created a User interface, an Admin interface that extends User, and demonstrated how to create and use objects conforming to these interfaces.

Conclusion

Congratulations, you've made it to the end of my blog—hurray!

In this journey through TypeScript, we've covered some essential topics to help you get started with your next project. Here's a quick recap:

  • Types: Making sure our variables follow specific data structures.

  • Union Types: Giving our variables the flexibility to hold values of different types.

  • Tuples: Creating arrays with fixed lengths and specific data types.

  • Interfaces: Defining the structure of our objects for consistency and clarity.

This blog is a result of my learnings from a YouTube course and the TypeScript documentation. Thank you for reading! I hope you found it useful and that you'll share it with others. It took a lot of effort to put this together, and I truly appreciate your support!

I know this isn't a comprehensive guide to TypeScript, but it's a great starting point for anyone looking to dive in and get a solid foundation. This blog is a result of my learnings from a YouTube course and the TypeScript documentation. Thank you for reading! I hope you found it useful and that you'll share it with others. It took a lot of effort to put this together, and I truly appreciate your support!

Additional Resources

If you're eager to learn more about TypeScript, here are some great resources:

  1. TypeScript Documentation: The official documentation is always a great place to start.

  2. TypeScript Handbook: Another great resource from the official TypeScript website.

  3. FreeCodeCamp TypeScript Course: This course by Hitesh Choudhary is an excellent free resource.

Happy coding, and good luck on your TypeScript journey!

1
Subscribe to my newsletter

Read articles from Nidhin M directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nidhin M
Nidhin M

Hey there! I'm a passionate software developer who thrives in the TypeScript world and its companions. I enjoy creating tutorials, sharing tech tips, and finding ways to boost performance. Let's explore coding and tech together! 🚀