Statistics
3
Views
0
Downloads
0
Donations
Support
Share
Uploader

高宏飞

Shared on 2026-03-04

AuthorMaksim Ivanov, Alex Bespoyasov, (ed) Nate Murray

No description

Tags
No tags
Publisher: Fullstack.io
Publish Year: 2021
Language: 英文
Pages: 600
File Format: PDF
File Size: 19.2 MB
Support Statistics
¥.00 · 0times
Text Preview (First 20 pages)
Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

(This page has no text content)
Fullstack React with TypeScript Learn Pro Patterns for Hooks, Testing, Redux, SSR, and GraphQL Written by Maksim Ivanov and Alex Bespoyasov Edited by Nate Murray © 2020 Fullstack.io All rights reserved. No portion of the book manuscript may be reproduced, stored in a retrieval system, or transmitted in any form or by any means beyond the number of purchased copies, except for a single backup or archival copy. The code may be used freely in your projects, commercial or otherwise. The authors and publisher have taken care in preparation of this book, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or consequential damagers in connection with or arising out of the use of the information or programs container herein. Published by \newline
Contents Book Revision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Join Our Discord Channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Be notified of updates via Twitter . . . . . . . . . . . . . . . . . . . . . . . . . 1 We’d love to hear from you! . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 How To Get The Most Out Of This Book . . . . . . . . . . . . . . . . . . . . 2 What is TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Why Use TypeScript With React . . . . . . . . . . . . . . . . . . . . . . . . . 9 A Necessary Word Of Caution . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Your First React and TypeScript Application: Building Trello with Drag and Drop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 What Are We Building? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Preview The Final Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 How to Bootstrap React + TypeScript App Automatically . . . . . . . . . . 17 App Layout. React + TypeScript Basics . . . . . . . . . . . . . . . . . . . . . . 30 Create The Card Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Render Children Inside The Columns . . . . . . . . . . . . . . . . . . . . . . 50 Component For Adding New Items. State, Hooks, and Events . . . . . . . . 52 Render Everything Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Add Global State And Business Logic . . . . . . . . . . . . . . . . . . . . . . 69 Using the useReducer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Implement State Management . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Adding Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
CONTENTS Moving Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Implement The Custom Dragging Preview . . . . . . . . . . . . . . . . . . . 114 Move The Dragged Item Preview . . . . . . . . . . . . . . . . . . . . . . . . . 120 Hide The Default Drag Preview . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Drag Cards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 Update CustomDragLayer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Update The Reducer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Drag the Card To an Empty Column . . . . . . . . . . . . . . . . . . . . . . . 133 Saving State On Backend. How To Make Network Requests . . . . . . . . . 135 Loading The Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 How to Test Your Applications: Testing a Digital Goods Store . . . . . . . . 157 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Initial Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 Writing Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Home Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Testing React Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Congratulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Patterns in React TypeScript Applications: Making Music with React . . . 237 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 What We’re Going to Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 What We’re Going to Use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 First Steps and Basic Application Layout . . . . . . . . . . . . . . . . . . . . 239 A Bit of a Music Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 Third Party API and Browser API . . . . . . . . . . . . . . . . . . . . . . . . . 257 Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Creating a Keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 Playing a Sound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 Mapping Real Keys to Virtual . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Instruments List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 Render Props . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 Higher Order Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 Using Redux and TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
CONTENTS What Are We Building? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 Preview The Final Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 What is Redux? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 Why Can’t We Use useReducer Instead of Redux? . . . . . . . . . . . . . . . 337 Initial Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 Prepare The Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 Working With Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 Handling Canvas Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 Define The Store Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 Add Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 Add The Reducer Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 Define The First Selector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351 Use The Selector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 Dispatch Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 Draw The Current Stroke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 Implement Selecting Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Implement Undo and Redo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 Splitting Root Reducer And Using combineReducers . . . . . . . . . . . . . 366 Exporting An Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 Using Redux Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 Configuring The Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 Using createAction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 Using createReducer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 Using Slices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 Remake The Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 Save And Load Data Using Thunks . . . . . . . . . . . . . . . . . . . . . . . . 394 Add Modal Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 Add The Modal Manager Component . . . . . . . . . . . . . . . . . . . . . . 397 Save The Project Using Thunks . . . . . . . . . . . . . . . . . . . . . . . . . . 401 Load The Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Define The ProjectsList Module . . . . . . . . . . . . . . . . . . . . . . . . . . 406 Static Site Generation and Server-Side Rendering Using Next.js . . . . . . . 413 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 What We’re Going to Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 Pre-Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
CONTENTS Next.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417 Setting Up a Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417 Creating A First Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419 Basic Application Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 Center Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 Footer Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 Custom App Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Application Theme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427 Custom Document Component . . . . . . . . . . . . . . . . . . . . . . . . . . 429 Site Front Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 Page 404 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 Post Page Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440 Backend API Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 Frontend API Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444 Updating The Main Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 Pre-Render Post Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 Category Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458 Adding Breadcrumbs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 Comments and Server-Side Rendering . . . . . . . . . . . . . . . . . . . . . . 464 Add Comments to Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 API for Adding Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 Adding Comments on Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 Converting Statically Generated Page to Rendered on Server . . . . . . . . 474 Connecting Redux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475 Optimizing Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484 Building Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 GraphQL, React, and TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 Is GraphQL Better Than REST? . . . . . . . . . . . . . . . . . . . . . . . . . . 495 What Are We Building? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 Preview The Final Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501 Setting Up The Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 Running Typescript in The Console . . . . . . . . . . . . . . . . . . . . . . . . 502 Authenticating in GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
CONTENTS Initializing The Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 Authentication Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509 Authenticating The ApolloClient . . . . . . . . . . . . . . . . . . . . . . . . . 515 GraphQL Queries - Getting The User Data . . . . . . . . . . . . . . . . . . . 516 Add The Panel Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 Define The WelcomeWindow Layout . . . . . . . . . . . . . . . . . . . . . . . 521 Getting GitHub GraphQL Schema . . . . . . . . . . . . . . . . . . . . . . . . 523 Generating The Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524 Adding Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525 Working With GitHub Repositories . . . . . . . . . . . . . . . . . . . . . . . . 528 Define The List Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532 Getting The Repositories List . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533 Define Form Helper Components . . . . . . . . . . . . . . . . . . . . . . . . . 539 GraphQL Mutations - Creating The Repositories . . . . . . . . . . . . . . . . 543 Getting The Repository ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551 Working With GitHub Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552 Getting The List Of Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556 Creating An Issue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560 Working With Github Pull Requests . . . . . . . . . . . . . . . . . . . . . . . 568 Getting The Pull Requests List . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 Creating A New Pull Request . . . . . . . . . . . . . . . . . . . . . . . . . . . 575 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587 Appendix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589 Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 Revision r11 (26-03-2021) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 Revision r10 (03-03-2021) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 Revision r9 (26-02-2021) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 Revision r8 (17-02-2021) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 Revision r7 (01-12-2020) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 Revision r6 (01-12-2020) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 Revision r5 (10-11-2020) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 Revision r4 (26-08-2020) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 Revision 3p (07-30-2020) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 Revision 2p (06-08-2020) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
CONTENTS Revision 1p (05-20-2020) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
CONTENTS 1 Book Revision Revision r11 - 2021-26-03 If you’d like to report any bugs or typos, join our Discord or email us below. Join Our Discord Channel If you’d like to get help, help others, and hang out with other readers of this book, come join our Discord channel: https://newline.co/discord/¹ Bug Reports If you’d like to report any bugs, typos, or suggestions just email us at:us@fullstack.io. Be notified of updates via Twitter If you’d like to be notified of updates to the book on Twitter, follow us at @full- stackio². We’d love to hear from you! Did you like the book? Did you find it helpful? We’d love to add your face to our list of testimonials on the website! Email us at: us@fullstack.io³. ¹https://newline.co/discord/ ²https://twitter.com/fullstackio ³mailto:us@fullstack.io
Introduction Welcome to Fullstack React with TypeScript! React and TypeScript are a powerful combination that can prevent bugs and help you (and your team) ship products faster. But understanding idiomatic React patterns and getting the typings set up isn’t always straightforward. This practical, hands-on book is a guide that will have you (and your team) writing React apps with TypeScript (and hooks) in no time. This book consists of several sections. Each section covers one practical case of using TypeScript with React. Your First React and TypeScript Application: Building Trello with Drag and Drop: Here you will learn how to bootstrap a React TypeScript application and all the basics of using React with TypeScript. We will build a kanban board application like Trello that will store its state on backend. Testing ReactWith TypeScript: Testing a Digital Goods Store: In this section you will set up your testing environment and learn how to test your application. We will take an online store application and cover it with tests. Patterns in React TypeScript Applications: Making Music with React: Here we cover Higher Order Components (HOCs) and render props React patterns. We show when are they useful and how to use them with TypeScript. In this section we will build a virtual piano that supports different sound sets. Next.js and Static Site Generation: Building a Medium-like Blog: React can be rendered server-side. It allows us to create multi-page interactive websites. In this section we cover the basics of server-side generation with React and then we build an advanced application using Next.js framework. The example application will be a blogging platform (like Medium). State Management With Redux and TypeScript Some React applications are so complex that they require use of some external state management library. Redux is a solid choice in this case. It is worth learning how to use it with TypeScript. In this
Introduction 2 section we will build a drawing application with undo/redo support. It will also let you save your drawings on backend. VI GraphQLWith React And TypeScript. GraphQL is a query language that allows us to create flexible APIs. Facebook, Github, Twitter and many other companies provide GraphQL APIs. TypeScript works pretty well with GraphQL. In this section we will build a Github issue viewer. We recommend you read this book in linear order, from start to finish. The sections are arranged from basic topics to more complex ones. Most sections assume that you are familiar with topics explained in previous sections. How To Get The Most Out Of This Book Prerequisites In this book we assume that you have at least the following skills: • basic JavaScript knowledge (working with functions, objects, and arrays) • basic React understanding (at least a general idea of component-based ap- proach) • some command line skill (you know how to run a command in terminal) We will mostly focus on the specifics of using TypeScript with React and some other popular technologies. The instructions we give in this book are very detailed, so if you lack some of the listed skills, you can still follow along with the tutorials and be just fine. Running Code Examples Each section has an example app shipped with it. You can download code examples from the same place where you purchased this book. If you have any trouble finding or downloading the code examples, email us at us@fullstack.io⁴. ⁴mailto:us@fullstack.io
Introduction 3 At the beginning of each section youwill find instructions on how to run the example app. In order to run the examples you need a terminal app and NodeJS installed on your machine. Make sure you have NodeJS installed. Run node -v to output your current NodeJS version: $ node -v v10.19.0 Here are the instructions for installing NodeJS on different systems: Windows To work with the examples in this book we recommend installing Cmder⁵ as a terminal application. We recommend installing node using nvm-windows⁶. Follow the installation instruc- tions on the Github page. Then run nvm to get the latest LTS version of NodeJS: nvm install --lts It will install the latest available LTS version. Mac Mac OS has a terminal app installed by default. To launch it toggle Spotlight, search for terminal and press Enter. Run the following command to install nvm⁷: ⁵https://cmder.net/ ⁶https://github.com/coreybutler/nvm-windows ⁷https://github.com/nvm-sh/nvm
Introduction 4 curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/inst\ all.sh | bash Then run nvm to get the latest LTS version of NodeJS: nvm install --lts This command will also set the latest LTS version as default, so you should be all set. If you face any issues follow the troubleshooting guide for Mac OS⁸. Linux Most Linux distributions come with some terminal app provided by default. If you use Linux you probably know how to launch the terminal app. Run the following command to install nvm⁹: curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/inst\ all.sh | bash Then run nvm to get the latest LTS version of NodeJS: nvm install --lts In case of problems with installation follow the troubleshooting guide for Linux¹⁰. Code Blocks And Context Code Block Numbering In this book, we build example applications in steps. Every time we achieve a runnable state we put it in a separate step folder. ⁸https://github.com/nvm-sh/nvm#troubleshooting-on-macos ⁹https://github.com/nvm-sh/nvm ¹⁰https://github.com/nvm-sh/nvm#troubleshooting-on-linux
Introduction 5 1 01-first-app/ 2 ├── step1 3 ├── step2 4 ├── step3 5 ... // other steps If at some point in the chapter we achieve a state that we can run, we will tell you how to run the version of the app from the particular step. Some files in that folders can have numbered suffixes with *.example: 1 src/AddNewItem0.tsx.example If you see this, it means that we are building up to something bigger. You can jump to the file with the same name but without a suffix to see a completed version of it. Here the completed file would be src/AddNewItem.tsx. Reporting Issues We have done our best to make sure that our instructions are correct and code samples don’t contain errors. There is still a chance that you will encounter problems. If you find a place where a concept isn’t clear or you find an inaccuracy in our explanations or a bug in our code, email us¹¹! We want to make sure that our book is precise and clear. Getting Help If you have any problems working through the code examples in this book, email us¹². To make it easier for us to help you, include the following information: • What revision of the book are you referring to? ¹¹mailto:fullstack-react-typescript@newline.co ¹²mailto:fullstack-react-typescript@newline.co
Introduction 6 • What operating system are you on? (e.g. Mac OS X 10.13.2, Windows 95) • Which chapter and which example project are you on? • What were you trying to accomplish? • What have you tried already? • What output did you expect? • What actually happened? (Including relevant log output.) Ideally also provide a link to a git repository where we can reproduce the issue you are having. What is TypeScript TypeScript is a typed superset of JavaScript that compiles to plain JavaScript - typescriptlang.org¹³. TypeScript allows you to specify types for values in your code, so you can develop applications with more confidence. Using Types In Your Code Consider this JavaScript example. Here we have a function that verifies that a password has at least eight characters: function validatePasswordLength(password) { return password.length >= 8; } When you pass it a string that has at least eight characters it will return true. validatePasswordLength("123456789") // Returns true Someone might accidentally pass a numeric value to this function: ¹³https://typescriptlang.org
Introduction 7 validatePasswordLength(123456789) // Returns false In this case the function will return false. Even though the function was designed to only work with strings you won’t get an error saying that you misused the function. It can cause nasty run-time bugs that might be hard to catch. With Typescript we can restrict the values that we pass to our function to only be strings: function validatePasswordLength(password: string) { return password.length >= 8; } validatePasswordLength(123456789) // Argument of type '123456789' is no\ t assignable to parameter of type 'string'. Now if we try to call our function with the wrong type, the TypeScript typechecker will give us an error. TypeScript typechecker can tell if we have an error in our code just by analyzing the syntax. That means that you won’t have to run your program. Most code editors support TypeScript so the error will be immediately highlighted when you try to call the function with the wrong value type. Strings and numbers are examples of built-in types in TypeScript. TypeScript supports all the types available in JavaScript and adds somemore.Wewill get familiar with a lot of them during the next chapters. But the coolest thing is that you can define your own types. Defining Custom Types Let’s say we have a greet function that works with user objects. It generates a greeting message using provided first and last names.
Introduction 8 function greet(user){ return `Hello ${user.firstName} ${user.lastName}`; } How can we make sure that this function receives an input of the correct type? We can define our own type User and specify it as a type of our function user argument: type User = { firstName: string; lastName: string; } function greet(user: User){ return `Hello ${user.firstName} ${user.lastName}`; } Now our function will only accept objects that match the defined User type. greet({firstName: "Maksim", lastName: "Ivanov"}) // Returns "Hello Maks\ im Ivanov!" If we try to pass something else, we’ll get an error. greet({}) // Argument of type '{}' is not assignable to parameter of ty\ pe 'User'. // Type '{}' is missing the following properties from type 'U\ ser': firstName, lastName Benefits Of Using TypeScript Preventing errors. As you can see with TypeScript we can define the interfaces for parts of our program, so we can be sure that they interact correctly. It means they
Introduction 9 will have clear contracts of communication with each other which will significantly reduce the amount of bugs. TypeScript contracts by which parts of your program communicate. If on top of that we cover our code with unit tests - BOOM, our application becomes rock-solid. Now we can add new features with confidence, without fear of breaking it. There is a research paper¹⁴ showing that just by using typed language you will get 15% fewer bugs in your code. There is also an interesting paper about unit tests¹⁵ stating that products where test-driven development was applied had between 40% and 90% reductions in pre-release bug density. Better Developer Experience. When you use TypeScript you also get better code suggestions in your editor, which makes it easier to work with large and unfamiliar codebases. Why Use TypeScript With React The revolutionary thing about React is that it allows you to describe your application as a tree of components. ¹⁴http://ttendency.cs.ucl.ac.uk/projects/type_study/documents/type_study.pdf ¹⁵http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.210.4502&rep=rep1&type=pdf
Introduction 10 A component can represent an element, like a button or an input. It can be a group of elements representing a login form. Or it can be a complete page that consists of multiple simple components. Components can pass the information down the tree, from parent to child. You can also pass down functions as callbacks, so if something happens in the child component it can notify its parent by calling the passed callback function. This is where TypeScript becomes very handy. You can use it to define the interfaces of your components, so that you can be sure that your component gets only correct inputs. If you have worked with React before you probably know that you can specify a component’s interface using prop-types. import PropTypes from 'prop-types'; const Greeting = ({name}) => { return ( <h1>Hello, {name}</h1> ); } Greeting.propTypes = { name: PropTypes.string }; If you can do this with prop-types, why would you need TypeScript? There are several reasons: • You don’t need to run your application to know if you have type errors. TypeScript can be run by your code editor so you can see the errors as you make them. • You can only use prop-types with components. In your application you will probably have functions and classes that are not using React. It is important to be able to provide types for them as well.
Introduction 11 • TypeScript is just more powerful. It gives you more options to define the types and then it allows you to use this type information in many different ways. We will demonstrate examples of this in the next chapters. A Necessary Word Of Caution TypeScript does not catch run-time type errors. It means that you can write the code that will pass the type check, but you will get an error upon execution. function messUpTheArray(arr: Array<string | number>): void { arr.push(3); } const strings: Array<string> = ['foo', 'bar']; messUpTheArray(strings); const s: string = strings[2]; console.log(s.toLowerCase()) // Uncaught TypeError: s.toLowerCase is no\ t a function Try to launch this code example in TypeScript sandbox¹⁶. You will get Uncaught TypeError: s.toLowerCase is not a function error. Here we said that our messUpTheArray accepts an array containing elements of type string or number. Then we passed to it our strings array that is defined as an array of string elements. TypeScript allows this because it thinks that types Array<string | number> and Array<string> match. Usually it is convenient because an array that is defined as having number or string elements can actually have only strings. ¹⁶https://www.typescriptlang.org/play/index.html?ssl=9&ssc=29&pln=1&pc=1#code/ GYVwdgxgLglg9mABAWwKYGd0FUAOAVAC1QEEAnUgQwE8AKC8gLkTMqoB50pSYwBzRAD6IwIZACNUpAHwBKJgDc4MACaIA3gFgAUIl2J6pAHQ4Q6AjQDMMgNzaAvtu0QEnRJ2590TFtQ5cevFKIALyIANoA5MBwcBEANIgRYvQRALq2WmiYuIQk5NQ07gHoNo5azmCuXm7+ fCE1HrzoYQBM6U4ucAA2qIZdcLyFhlBwADJwAO6SAMIU6Kg0MjLaQA