butadpj's logo butadpj

The Only TypeScript Introduction That You Need

Published: August 5, 2024
TypeScript Introduction Programming
Blog's background image

Can’t find good tutorials?

I know, it’s really hard to find good tutorials out there that teaches you how to get started with TypeScript. Short, straight to the point, while teaching all you need to know so you can start using TypeScript on your future projects. Well, good news! I’m here to fill all those gaps so let’s get started.

The starting point

TypeScript sheds light to what's possible

There’s no special thing about TypeScript. It’s more accurate to say, that JavaScript is lacking or incomplete when it comes to building complex projects. Sure, you can build complex projects using only JavaScript. But, to make the codebase maintainable and your mental health “healthy” 😜, JavaScript alone is not enough. It’s only when you use TypeScript, that you can see what’s possible. Let’s have the example code below.


  // JS version
  function formatPrice(price, options) {
    // logic here
  }

  // TS version
  function formatPrice(
    price: number // 👈 extra code,
    options: { 
      withoutTag?: boolean         // 👈 extra code; 
      withoutDecimals?: boolean    // 👈 extra code; 
    }                         
  ) {
    // logic here
  }

Those extra codes you added are what we called types. Types enhance developer experience as you can get suggestions and code autocompletion from your IDE ⚡️.

VS Code's intellisense and autocompletion
  • Typical dev experience with TypeScript 🔥
  • Look at the errors I’m getting when I’m not using the function correctly 🚫
VS Code's intellisense and autocompletion
  • Now the typical dev experience with JavaScript 🫤
  • I could be getting errors but I still have no idea. I guess we’ll figure it out when it’s on production 🫤

There’s two (2) things where TypeScript is really good at, that will also speed up your development time ⚡️.

So, now are you ready? Let’s setup TypeScript!

What are you building? - Setting up TypeScript

Simson reference gif

For every type of project you want to do, there are different ways you can setup TypeScript. But, regardless of type of project you are building, the requirements for using TypeScript is going to be the same:

Plain stack web application (HTML, CSS, JS):

To use TypeScript on your plain stack web application

  1. Make sure you have Node.js in your machine - download here

  2. In your project’s root directory, initialize package.json file

    • npm init -y
  3. Install TypeScript

    • npm install typescript --save-dev
  4. Initialize tsconfig.json file

    • npx tsc --init
  5. Starting from now, instead of writing codes in JavaScript .js files, you’re going to write in TypeScript .ts files. So, go ahead and create your first .ts file.

    • 
       // 🗂️ main.ts
       window.onload = (e: Event) => { 
         // do something
       }
      
  6. Using tsc, compile your TypeScript .ts file to JavaScript .js

    • npx tsc
    • npx tsc --watch (automatically recompile your code when you make changes)
  7. You should see a main.js being created.

    • 
       // 🗂️ main.js
       "use strict";
       window.onload = (e) => {
         // do something
       };
      
      
  8. Same goes if you already have JavaScript .js files. You can start converting them to TypeScript .ts files and run
    npx tsc to compile them to .js files

    • 
       // add.js
       function add (num1, num2) {
         return num1 + num2
       }
       👇👇👇
       // add.ts
       function add(num1: number, num2: number): number {
         return num1 + num2;
       }
      
      
       // index.js
       window.onload = (e) => { 
         // do something
       }
       👇👇👇
       // index.ts
       window.onload = (e: Event) => {
         // do something
       };
      
      

Framework-powered web applications (React, Next.js, AstroJS, Angular):

A lot of modern web frameworks, during setup, prompts you if you want to use TypeScript. Modern web frameworks also make sure you are doing best practices when using TypeScript.

Setting up Next.js w/ TypeScript

  • Next cli setup

Setting up React (via Vite) w/ TypeScript

  • React (via Vite) cli setup

A lot easier right? But, what if, you’re not using these modern web frameworks? No worries, whatever JS web framework you choose (as long as it has support for TypeScript), go to its documentation and find the “TypeScript” section. There, you will see the details on how to setup TypeScript manually.

How to learn TypeScript?

You can start by learning TypeScript’s basic types (number, string, boolean, array, object, null, undefined). You’re probably already familiar with them unless you’re completely new to programming.

Now you can start specifying the types of your variables, function parameters and return values.


  // Syntax #1: colon ":"
  let firstName: string = 'Jane';
  let yearsOld: number = 25;

  // Syntax #2: "as"
  let lastName = 'Oolah' as string;
  let favoriteColors = ["Red", "Blue"] as string[];

  let ids: number[] = [101, 102, 103]; 
  let ids: Array<number> = [101, 102, 103]; // This works too!


  //       typing the parameter   typing the parameter          
  //                 👇            👇           👇  typing the return value  
  function greet(name: string, age: number): string {
      return `Hello, ${name}!`;
  }

  //       typing the parameter   typing the parameter          
  //                 👇            👇           👇  typing the return value    
  const greet = (name: string, age: number): string => {
    return `Hello, ${name}!`;
  };

  // Typing a more complex data structure (e.g. Objects or array of objects)     
  type User = {
    id: string;
    name: string;
    age: number;
    favoriteColors: string[] // Array<string> works too!
  };

  //  Typing an object
  //        👇
  const user: User = {
    id: "aBVX26jl2328",
    name: 'Alice',
    age: 22,
    favoriteColors: ["Red", "Black"]
  }

  //  Typing an array of objects. Array<User> works too!
  //        👇
  const users: User[] = [
    {
      id: "aBVX26jl2328",
      name: 'Alice',
      age: 22,
      favoriteColors: ["Red", "Black"]
    },
    {
      id: "lTOJ51am5113",
      name: 'Paul',
      age: 20,
      favoriteColors: ["Green", "Blue"]
    }
  ]

  //     You can also use the type User here or to other values
  //                    👇
  function printUser(user: User): string {
    console.log(`Name: ${person.name}, Age: ${person.age}`);
  }
Not that hard right? You’re just typing a colon:”, or “as”, followed by the type you want to specify

But, uh oh, hold on! ✋. This is not how you use TypeScript correctly. You’re just unnecessarily writing more codes if you explicitly declaring types everywhere 😩. TypeScript is smart enough to figure out the type of the value you just declared and carry that type to other places (we call this type inference). Now, this is where you should focus when learning TypeScript!

Type inference

Just remember, you don’t need to declare types all the time 😊.


  // Example 1: Type inference with primitives
  let name = 'Alice'; 
  let age = 30; 

  // infers 'name' as type 'string'
  console.log(name.toUpperCase()); // Has string methods ✅

  // infers 'age' as type 'number'
  console.log(age.toFixed(2)); // Has number methods ✅
  


  // Example 2: Type inference with arrays and objects
  let numbers = [1, 2, 3]; 
  let person = { name: 'Bob', age: 25 };

  console.log(numbers.map(n => n * 2)); // Valid array of numbers ✅
  console.log(person.name.toUpperCase()); // person.name is a valid string with string methods ✅   

Let’s have a more real-world examples 🙂


  // main.ts

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

  // Function to fetch users from an API
  const fetchUsers = async () => {
    const response = await fetch(`/api/users`);
    if (!response.ok) {
      throw new Error("Failed to fetch users");
    }
    // This is the only time we explicitly type a value
    const userData: User[] = (await response.json()); 
    // const userData = (await response.json()) as User[]; // this works too!    

    return userData; 
  };

  // fetchUsers() returns Promise<User[]> 
  fetchUsers().then((data) => {
    const users = data; // infers 'data' as type 'User[]'

    const usersAge = users.map((user) => user.age);

    console.log(usersAge) // usersAge has a type of number[]
  })

Conclusion

You have learned that TypeScript’s type system allows you to detect errors ahead of time and provide better dev experience, making it possible for you to make big changes in your codebase very easily and quickly 👌⚡️.

When setting up TypeScript, it depends on the project you’re building. You can install the needed packages and configure TypeScript manually or if you’re using web frameworks (React, Next.js, AstroJS, Angular), they usually have built-in TypeScript support.

When learning TypeScript, once you have grasp the basic types, you don’t need to explicitly type every values (variables, parameters, return values). By using type inference, you can just focus on the logic and structure of your code rather than writing unnecessary boilerplate codes.

A master bowing