Writing React Components with Typescript
Tags: typescript, react
Published: 2021-08-29 14:12:04

##### Typescript and React have been a powerful combination

* I've found that people are afraid to move to typescript because they think that writing typescript requires a lot of boilerplate.
* Believe me, i was one of those people. I used to think the same way until i met typescript. I'll agree that at the beginning it was a bit intimidating with all the types and everything but it's fun once you get the hang of it.
* Once you start using typescript, going back to Javascript feels like you've lost some power😅.At least that's what i found in my experience.
* I want to take out your fear of using typescript with react and help you get started in a way that you don't feel so intimidated.
* We are going to write a Functional Component using react and typescript.

##### Functional components with TypeScript
* You can create functional components in TypeScript just like you would in JavaScript.

* The main difference is the `FC` interface, which stands for Function Component. We use this to tell TypeScript that this is a React function component and not just a regular function.
* Optionally, we can add types for the props by defining an interface and passing it to the generic `FC`.
* A functional component then typically looks like this:
```javascript 
import React, { FC } from 'react';

interface TitleProps {
  title: string;
}

const Title: FC<TitleProps> = ({ title, subtitle }) => {
  return (
    <>
      <h1>{title}</h1>
      <h2>{subtitle}</h2>
    </>
  );
};

export default Title;
```
* Now, if we go ahead and use this component in our react application, we will get some benefits like
  * code autocompletion
  * compilation errors in our editor that warn us when we 
    forgot a property or use the wrong types.

![Type Error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrvvyuompu8lsu94spdh.png)

###### Note
 * Generic types in TypeScript are like functions that accept 
   parameters. Instead of parentheses, generic types 
   use angle brackets `(<>)`.
 * For the `FC` interface, you don't need to pass any 
   parameters, so you could use it without a generic type by 
   omitting the angle brackets altogether when your component 
   doesn't accept any props:

 ```javascript 
 const Title: FC = () => {
  // ...
 } 
 ```
##### Optional props
* Not all of the props that you pass to components are need to be required. 
* We can make a props optional by adding a question mark to the interface:

```javascript 
 interface TitleProps {
  title: string; // required
  subtitle?: string; // optional
 }
```
* This will allow you to omit the prop when you don't need it.

##### Alternatives to the FC interface

* If you know TypeScript, you might think why I'm not applying the prop interface to the function parameters itself.
```javascript 
const Title = ({ title, subtitle }: TitleProps) => {
  // ...
}
```
* this syntax works fine and you can write functions in typescript like this.
* But, there is a specific reason as to why you want to use a generic type like `FC` because it comes with all the types that are required by a functional component.
* this includes the implicit `children` prop. because this becomes a default prop in any functional component that you define with `FC` interface, we don't need to add it to our interface.
```javascript 
import React, { FC } from 'react';

interface TitleProps {
  title: string;
  subtitle?: string;
}

const Title: FC<TitleProps> = ({ title, subtitle, children }) => {
  return (
    <>
      <h1>{title}</h1>
      <h2>{subtitle}</h2>
      <div>{children}</div>
    </>
  );
};

export default Title;
```
* Sometimes it's a disadvantage because `FC` interface always adds the children prop, regardless of whether you use it or not.

##### Type-safe state in function components

* To have type-safety for the state in functional components, we don't necessarily need to modify our code: The `useState` hook inherits the type from the value we use to initialise it.
* If we use a more complex type or don't initialize the state, we can pass the type like the following:

```javascript 
const [title, setTitle] = useState<string>(null); 
```