Unlocking the Power of TypeScript in React Applications

Setting Up a New Project with TypeScript

To get started with TypeScript in React, we’ll use Create React App to set up our project. Run the command:

npx create-react-app my-app --template typescript

Once the project is set up, we can explore the differences between a JavaScript and TypeScript project.

The TypeScript Compiler

The TypeScript compiler plays a vital role in converting our TypeScript files into JavaScript files that can be understood by web browsers and Node.js. The compiler uses different file extensions to distinguish between pure JavaScript files and TypeScript files that need to be compiled. For example, component files are now .tsx instead of .js or .jsx, and files like setupTests.js are now setupTests.ts.

Typing Variables in TypeScript

Unlike JavaScript, TypeScript allows us to assign a data type to a variable. We can do this either implicitly by letting TypeScript infer the type based on the value assigned to the variable or explicitly by declaring the type during variable declaration. For instance, we can declare a variable with an explicit type like this:

let helloWorld: string = 'Hello, World!';

Setting Up a New React Application with TypeScript

React works seamlessly with JavaScript, but using TypeScript can reduce bugs and errors, make codebases more predictable, and improve component utilization. To set up a new React application with TypeScript, run the command:

npx create-react-app my-app --template typescript

Then, start the project with the commands:

cd my-app
npm start

Remote Data Types

When working with remote data, we need to define a custom data type to represent the JSON response. We can do this by creating a GitHub.ts file in the src directory and defining a custom data type using the type syntax. For example, we can define a GitHubSearchResultType that includes properties like total_count, incomplete_results, and items:

interface GitHubSearchResultType {
  total_count: number;
  incomplete_results: boolean;
  items: Array<{ id: number; name: string }>;
}

Building Components: Listing Repositories

Now that we have our custom data type, we can build a component that lists repositories. We’ll create a ListRepositories.tsx component that receives a list of repositories as props. We can define the props using an interface, and then use the React.FC type to create a functional component:

interface ListRepositoriesProps {
  repositories: GitHubSearchResultType['items'];
}

const ListRepositories: React.FC<ListRepositoriesProps> = ({ repositories }) => {
  // component implementation
};

Creating the Search Form

Next, we’ll build a search form component that captures user input and initiates the search operation. We can define the props using an interface, and then use the React.FC type to create a functional component. We’ll also use TypeScript’s casting feature to ensure that the formData.get function returns a string:

interface SearchFormProps {
  onSubmit: (searchQuery: string) => void;
}

const SearchForm: React.FC<SearchFormProps> = ({ onSubmit }) => {
  const formData = new FormData();
  const searchQuery = formData.get('searchQuery') as string;

  // component implementation
};

API Fetching and Putting it All Together

Finally, we’ll combine our components and add the functionality to fetch remote data from the GitHub API using Axios. We’ll use TypeScript generics to define the type of the data returned by the API:

interface AxiosResponse<T> {
  data: T;
}

const fetchRepositories = async (searchQuery: string): Promise<AxiosResponse<GitHubSearchResultType>> => {
  const response = await axios.get(`https://api.github.com/search/repositories?q=${searchQuery}`);
  return response.data;
};

By leveraging the power of TypeScript, we can build scalable and maintainable React applications with ease. With its ability to add types to variables, TypeScript makes it easier to understand complex codebases and reduces errors.

Leave a Reply