DEV Community

Cover image for JavaScript to TypeScript | Complete Guide with React βš›οΈ
SUCHINTAN DAS
SUCHINTAN DAS

Posted on

JavaScript to TypeScript | Complete Guide with React βš›οΈ

Table of Content


πŸ“Œ Introduction

πŸ“Œ Introduction to TypeScript

➑ Variables

➑ Functions

➑ Multiple Types

➑ Classes

πŸ“Œ React TypeScript Project Structure

➑ Models

➑ Apis

➑ Components

➑ Pages

πŸ“Œ Thank you


Introduction

Hello amazing developer πŸ§‘β€πŸ’», before digging into this topic let me give you a small introduction and so instructions. Don't worry it would be quick and crisp.

I am Suchintan Das, a Full Stack Developer currently working over two startups. I have been into web development for past two years.

Connect me on πŸ‘‰ Linkedin

The whole syntaxes and code are uploaded on this πŸ‘‰ Repository . If you find it useful , you can star the repository to show a appreciation. Thanks !


Introduction to TypeScript

I know most of you guys who are reading this blog are either not familiar with TypeScript or have a little knowledge about TypeScript as a whole. Don't worry in this whole blog we are going to cover every single thing from the start to bottom and even if you are new to TypeScript you can build a good project easily along with React.

Let's first understand some important syntaxes of TypeScript !

I will be explaining the syntaxes considering that you are coming from JavaScript background and have knowledge about the syntaxes of the same !

Yes Meme


Variables

JavaScript 🟑


let a = "check";
let b= 2;
let c= {
    h: "element"
};
let d= [1,2,3];
let e= false;
let f= ["check",2]
let g= c.h;
let i=null
let j=undefined
let k= [
    {
        h:"element1"
    }
]

Enter fullscreen mode Exit fullscreen mode

TypeScript πŸ”΅


let a: string = "check";

let b: number = 2;

interface ctype {
    h:string
}
let c: ctype = {
  h: "element",
};

let d: Array<number> = [1, 2, 3];

let e: boolean = false;

let f: [string, number] = ["check", 2]; //tuple

let g: string = c.h;

let h: unknown = "noideaabout"; //a variable whose type is not known it could be a string, object, boolean, undefined, or other types but not number

let i:null=null

let j:undefined=undefined

let k: Array<ctype> = [
    {
        h:"element1"
    }
]


Enter fullscreen mode Exit fullscreen mode


Functions

JavaScript 🟑


let func1= (arg1) => {
    return "str"
}

let func2 = (arg2) => {

}

Enter fullscreen mode Exit fullscreen mode

TypeScript πŸ”΅


const func1 = (arg1: number): string  => {
    return "str";
};


const func2 = (arg1: number): void  => {

};

Enter fullscreen mode Exit fullscreen mode


Multiple Types

JavaScript 🟑


function randomfunc(arg) {
    // ...
  }
  randomfunc({ shape:"check1" });
  randomfunc({ shape:undefined, xPos: 100 });
  randomfunc({ shape:2, yPos: 100 });
  randomfunc({ shape:"check1", xPos: 100, yPos: 100 });

Enter fullscreen mode Exit fullscreen mode

TypeScript πŸ”΅


interface typeOptions {
    shape: string | undefined | number;  //multiple types to same parameter
    xPos?: number;  //optional parameters
    yPos?: number;  //optional parameters
  }
function randomfunc(arg: typeOptions) {
    // ...
  }
  randomfunc({ shape:"check1" });
  randomfunc({ shape:undefined, xPos: 100 });
  randomfunc({ shape:2, yPos: 100 });
  randomfunc({ shape:"check1", xPos: 100, yPos: 100 });

Enter fullscreen mode Exit fullscreen mode


Classes

JavaScript 🟑


class Check {
    a;
    b;
  }

const ch = new Check();
ch.a = 0;
ch.b = "check-string";


Enter fullscreen mode Exit fullscreen mode

TypeScript πŸ”΅


class Check {
    a: number;
    b: string;
  }

const ch = new Check();
ch.a = 0;
ch.b = "check-string";

Enter fullscreen mode Exit fullscreen mode


Now that we are familiar with all the syntaxes of TypeScript we can now dive into React with TypeScript full project setup.

Let's go !


React TypeScript Project Structure


Here's a small peak to the Project :

Project Peak

Let's start the React Project with TypeScript Template using the command


npx create-react-app client --template typescript

Enter fullscreen mode Exit fullscreen mode

Note: To explain the whole structure I will be making a todo list project so that everyone can get an idea how to implement the same on any other project or product.


React TypeScript with Project


Models

Models

ITask.ts


export interface Tasks {
    id: number,
    title: string,
    content: string
}

export interface TaskList extends Array<Tasks>{}

export interface TasksProps {
    d: TaskList | undefined,
    changed: Function
  }

Enter fullscreen mode Exit fullscreen mode

Here's you can see for this project there are 3 interfaces that I used. First interface Tasks is description of elements of the Array of Objects and the second interface TaskList is the declaration of array of the interface Tasks.

Thirdly there is another interface TasksProps which is used here to describe all the props typing while passed between components.


Apis

Api's

Task.ts


import axios          from "axios";
import { TaskList, Tasks } from "../../models/ITask";
import { token } from "../../utils/authController";

const baseUrl = "http://localhost:5000";


//receive tasks
export const getTasks = async () => {
    try {
        const response = await axios.get(
            baseUrl + '/tasks/gettasks', { headers: { 'Authorization': `bearer ${token}`, } });
        return response.data as TaskList;
    } catch (e) {
        console.log(e);
    }
};

//add tasks
export const postTasks = async (data:Tasks) => {
    try {
        const response = await axios.post(
            baseUrl + '/tasks/addtasks', data, { headers: { 'Authorization': `bearer ${token}`, } });
        return response.status as number;
    } catch (e) {
        console.log(e);
    }
};

Enter fullscreen mode Exit fullscreen mode

Here I have used axios for making backend calls. The preference can go different for you ! The main idea here is to make a typing of arguements and return types each function would be having so that any developer can make a call in the right syntax and do get the desired form of response body.


Controllers

Controllers

authController.tsx


export const token=localStorage.getItem("idtoken") as string

Enter fullscreen mode Exit fullscreen mode

Controllers are an essential element for frontend developers. Things which decide the flow of the website , are mostly the controllers of a website. Like here the authentication part is put into the controllers as it would be a flow decider for mostly all the components.


Components

Components

Header.tsx


import React, { useState } from 'react'
import './Header.css'

const Header = () => {
  return (
    <nav>
      <h1>Todo List</h1>
    </nav>
  )
}

export default Header

Enter fullscreen mode Exit fullscreen mode

TaskInput.tsx


import React, { useState, useEffect } from "react";
import { postTasks } from "../../apis/Tasks/Task";
import { TasksProps } from "../../models/ITask";
import Home from "../../pages/Home/Home";
import "./TaskInput.css";

export const TaskInput: React.FC<TasksProps> = ({ d, changed }: TasksProps) => {
  //states
  const [callapi, setcallapi] = useState<Boolean>(false);
  const [sendd, setsendd] = useState<Boolean>(false);
  const [content, setcontent] = useState<string>("");
  const [title, settitle] = useState<string>("");

  console.log("TaskInput")
  console.log(d)

  //api-call
  useEffect(() => {
    const senddata = () => {
      postTasks({id:d?.length!+1, title: title, content: content})
        .then((res) => {
          if (res === 200) {
            let updatedata: Array<Object> | undefined = d;
            updatedata?.push({
              id: d?.length! + 1,
              title: title,
              content: content,
            });
            console.log(updatedata)
            changed(updatedata);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    };

    if(sendd)
    {
      senddata();
      changed([]);
    }
  }, [callapi]);

  return (
    <div className="taskinput">
      <h1>Add Tasks</h1>
      <input type="text" placeholder="title" onChange={(event)=> {
          settitle(event?.target?.value)
        }}/>
      <textarea
        name="content"
        id=""
        cols={20}
        rows={10}
        placeholder="content"
        onChange={(event)=> {
          setcontent(event?.target?.value)
        }}
      ></textarea>
      <div className="add">
        <button onClick={()=> {
          setsendd(true);
          callapi ? setcallapi(false) : setcallapi(true);
        }}>Add</button>
        <i className="fa-solid fa-plus"></i>
      </div>
    </div>
  );
};

export default TaskInput;

Enter fullscreen mode Exit fullscreen mode

Tasks.tsx


import React, { useEffect, useState } from "react";
import { getTasks } from "../../apis/Tasks/Task";
import { TaskList, TasksProps } from "../../models/ITask";
import "./Tasks.css";

export const Tasks: React.FC<TasksProps> = ({ d, changed }: TasksProps) => {
  //states
  const [callapi, setcallapi] = useState<Boolean>(false);

  console.log("Tasks")
  console.log(d)


  //api-call
  useEffect(() => {
    const receivedata = () => {
      getTasks()
        .then((res) => {
          changed(res);
        })
        .catch((error) => {
          console.log(error);
        });
    };

    receivedata();
  }, [callapi]);

  return (
    <div className="tasks">
      {d?.map((ele) => {
        return ele !== null ? (
          <div className="task" key={ele.id}>
            <h1>{ele?.title}</h1>
            <p>{ele?.content}</p>
          </div>
        ) : (
          null
        );
      })}
    </div>
  );
};

export default Tasks;

Enter fullscreen mode Exit fullscreen mode

Here's a small summary of all the components . TaskInput component is sent two props whose typing are already been declared on models . The props are the states sent from parent component Home.tsx to TaskInput.tsx and Tasks.tsx so any changes in any of the child component gets reflected on the other component.

The api calls also have been declared already and the function call is made from the components for the data.


Pages

Pages

Home.tsx


import React, { useState } from 'react'
import Header from '../../components/Header/Header'
import TaskInput from '../../components/TaskInput/TaskInput'
import Tasks from '../../components/Tasks/Tasks'
import { TaskList } from '../../models/ITask'
import './Home.css'

const Home = () => {
  const [data, setdata] = useState<TaskList|undefined>([]);
  return (
    <>
    <Header/>
    <div className="dashboard">
      <TaskInput d={data} changed={setdata}/>
      <Tasks d={data} changed={setdata}/>
    </div>
    </>
  )
}

export default Home

Enter fullscreen mode Exit fullscreen mode

The states for data are declared on the parent component and sent as props to child components to make data changes on any child components reflect back to the other child.

It's possible as the pointer to the state is sent to the childrens.


Thank you

You have made it till the end of this blog πŸ€—. More such blogs are on the line .

It would be encouraging if a small comment would be there on the blog. I go through each one of them so do comment πŸ˜‰.

If you want to get a notification πŸ”” when it would be published , don't forget to tap on the follow button ☝.

And at last I want to say πŸ‘‡

Keep coding #️⃣ , keep rocking πŸš€

Top comments (4)

Collapse
 
fyodorio profile image
Fyodor

There's lot of information on how to get started with TS, and in React specifically. What is lacking a bit is why and when (for which projects?) you should switch to TS (and for which you should stick with JS further). It would be interesting to see some perspectives on that topic.

Because TS is great and all, but sometimes you just want (and need) the freedom (and hacks, and fun) that JS gives.

I'm saying it without any prejudice as I mostly write TS actually.

Collapse
 
suchintan profile image
SUCHINTAN DAS

Thanks Fyodor for the feedback πŸ™‚. I would surely cover this topic soon. And Yes, I also use TS for some project and stay with JS for some projects.

It would surely be interesting to do a broad research and put forward this topic.

Collapse
 
suchintan profile image
SUCHINTAN DAS

You can click on the follow button πŸ‘† if you want to recieve a notification πŸ”” whenever it get's published.

Thanks in advance .

Collapse
 
suchintan profile image
SUCHINTAN DAS

Guys if you want me to cover any topic πŸ’­ , you can comment here . I assure you that I maintain a good list of such topics and will surely cover them soon.

I always believe in sharing valuable knowledge with my connections. And if I can share knowledge about a needy topic , it's a pleasure for me .

Do comment below πŸ‘‡!