Learning TypeScript with React - Part 1
Tags: typescript, react, beginners, webdev
Published: 2019-07-01 18:30:29

---
title: Learning TypeScript with React - Part 1
published: true
description: Two weeks ago, I decided to pick up TypeScript so I started learning it by creating  a Tedx Talks player built together with React. It fetches the videos from the official Tedx Talks Youtube channel for you to watch. 
cover_image: https://thepracticaldev.s3.amazonaws.com/i/6wtom4ur95ut3iz9g77v.png
tags: typescript, reactjs, beginners, webdev
---

:zap:TL;DR: _Understanding what are types, type annotations, why use them and how to use them can help you catch errors during development while also enhancing code quality and readability._

Two weeks ago, I decided to pick up TypeScript so I started learning it by creating [TEDFlix](https://tedflix.netlify.com/ "TEDx Talks Player built with React and Typescript | Ana Liza Pandac"). Built together with React, it fetches the videos from the official [Tedx Talks](https://www.youtube.com/channel/UCsT0YIqwnpJCM-mx7-gSA4Q target="_blank") Youtube channel for you to watch. Why TEDFlix? It sounds fun and honestly, I ran out of ideas :stuck_out_tongue:


In this two-part series, I wanted to share what I learned from doing this project. 

Before diving into it, let me give you a short definition of what is TypeScript (TS) taken from the official TS website.

> “TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.”

Now, let me also give you a high level overview of the app’s features and how the React side is structured. 

It is a one page app where _it has a video player, a list of related talks and a search bar_ which are all built as separate React components. On page load, it fetches a default list of talks from a JSON file instead of fetching from Youtube to avoid exceeding the daily usage quota of the Youtube API when the page is loaded by many users. The app only communicates with Youtube when searching for talks.


Okay, let's start.

### First, the project setup

I generated the project using Create React App with TypeScript

```sh
create-react-app my-app-name --typescript
```

## **How did I use TypeScript in this app?**

Since I’m a TS beginner, I get started by learning the syntax and features of the language first _specifically the types, type annotations and interfaces_. In this first post, I'm gonna be talking about types and annotations only. 

### **What is a type?**
Since TypeScript is a typed language, it means we can specify/annotate the type of the variables, function parameters and object properties. 

**From my own understanding, a type is a symbol/representation of all the properties and methods that a variable has access to.** It means if we added a type of **`number`** to a variable, the TS compiler knows that _the variable has and can only access all the properties and methods that a number has_.
 
![](https://thepracticaldev.s3.amazonaws.com/i/am8chbwe2wbt9n8hnft6.gif)

> A type is annotated to the variable, parameter or property using this format **`:type`**. 
> For example, `let name: string`.

There are a lot of available types in TS however, in this app, these are the ones that I've used:
1. **Primitive Types**  - number, string, boolean
2. **Arrays** -  by adding `[]` after the type (e.g. `let names: string[]`)
3. **Video** - an interface or a custom type I created to represent a video object's properties


See [here](https://basarat.gitbooks.io/typescript/docs/types/type-system.html) for a more comprehensive list of types.

### **Why do we care about annotating types?**
1. **Types are one of the best forms of documentation you can have.** This is a very helpful to the next developer who has to read your code _which could also be the future you_.
2. **It helps the TypeScript compiler help you.** If you annotate a variable as a number and a few lines later assigned it a value which is a string, the compiler will give you the following error.

```javascript
let x: number = 123;
x = '123'; // Error: cannot assign a `string` to a `number`
```

Even if we remove the `:number` annotation from variable `x`, the same error will be given by the compiler because **TypeScript is smart***. 

> \*If you declare a variable with a value without specifying the type, **TypeScript will figure out the type of the variable based on the initial value assigned to it.** 

> This is called **type inference**.

_"So if type inference is present then why do I have to bother annotating the variables?"_

**Type inference does not work all the time.**

An example scenario is when you delay the initialization of a variable as shown below.
```javascript
let age;

// a few lines later
age = 12; 
// The compiler will NOT give an error even 
// if we assign a non-numeric value to `age`
age = 'Ana'; 
```

If you delay the variable initialization without annotating a type to it, the variable will automatically have a type of **`any`** associated with it since the TS compiler does not have any idea what kind of properties `age` will have later on.

**Variables with a type of `any` should be avoided as much as possible.** It defeats the purpose of the idea behind the TS type system where we want to catch as many errors as possible during development. Why? Because, the compiler cannot do error checking on types of `any`.

**Remember, use types to help the TS compiler help you.**

### **How is type annotation used in the app?**
Aside from using types on the variable declarations, I also used annotations in the function declarations.

A function can be annotated in the following ways:
#### 1. Arrow function

```javascript
const add = (a:number, b:number):number => {
 return a + b;
}

// or
const add: (a: number, b: number) => number = (a, b) => {
  return a + b;
};
```
#### 2. Non-arrow function
```javascript
function add(a:number, b:number):number {
 return a + b;
}
```

In both of these examples, the compiler will give an error if the function returns a string or any type that is not a number _since it is expecting a number_.

For fetching the channel's videos, I created a function called **`fetchChannelVideos`** which accepts a boolean flag indicating whether to fetch the default videos from the JSON file and a search query string.  Both of these are optional parameters (by adding **`?`** after the property name) which are represented as an interface. I will explain later what an interface is but for now let’s take a closer look on how the function is annotated.

```javascript
interface FetchVideosArguments {
 shouldUseDefaultVideos?: boolean;
 searchQuery?: string;
}

export const fetchChannelVideos: (
 args: FetchVideosArguments
) => Promise < Video[] > = async ({
 shouldUseDefaultVideos = false,
 searchQuery
}) => {};
```

On the left side of the assignment operator (`=`),

```javascript
const fetchChannelVideos: (args: FetchVideosArguments) => Promise <Video[]>
```

_we are annotating the variable **`fetchChannelVideos`** that was declared **not the function assigned**_. We are telling the TS compiler that this variable will have a function assigned to it with these types of arguments and return value.

While the right part of the `=` is the function assigned.

```javascript
async ({
 shouldUseDefaultVideos = false,
 searchQuery
}) => {};
```

To annotate the function itself, we have to specify its arguments and their types and the return value as well. 

> _So why didn't I annotate the function to assigned to **`fetchChannelVideos`**?_ Because again, TypeScript is smart.


Seeing that I assigned the function to a variable that was annotated, it is able to infer that the function will have the same argument names and types and the return value as well, otherwise it will give an error if I add or specify different argument names or return a different value. 

![](https://thepracticaldev.s3.amazonaws.com/i/x7syqxtc3he7ih85bjmw.gif)*\*The function arguments and return value is inferred*

**However**, if I’m exporting the function directly without assigning it to a variable then I have to annotate it like below.

```javascript
export async function fetchChannelVideos({
 shouldUseDefaultVideos = false,
 searchQuery
}: FetchVideosArguments): Promise<Video[]> {
 // function body
}
```


Okay, now that we have an idea about the what, why and how of type annotations, there's one last question.

### **Where do we use types?**

The answer is: **everywhere**. By using TypeScript, every data in your application will have a type associated with it whether you like it or not.

## **Closing Thoughts**

I have only touched the basics so far but I’ve already seen how helpful it is, seeing the errors the compiler gives while writing the code instead of discovering them later when running the app saved me a lot of time.

### **Learning Resources**

If you want to learn more and join me on this journey, here are some available resources that can help you get started.

[TypeScript in 5 Minutes](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html)

[TypeScript Deep Dive](https://basarat.gitbooks.io/typescript/)

[Official TypeScript Documentation](https://www.typescriptlang.org/docs/handbook/basic-types.html)

---
I deployed the app in Netlify: [https://tedflix.netlify.com/](https://tedflix.netlify.com/)

I will share the Github repo of the project soon.

---

**\*Update: 06/07\***
Last part about interfaces is up :tada:
{% link https://dev.to/analizapandac/learning-typescript-with-react-part-2-the-what-why-and-how-of-interfaces-1033 %}

---

Let me know in the comments below if you have any feedback and suggestions or pointers on where to go next. Thank you in advance.

Cheers!