├── .DS_Store └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anisul-Islam/react-typescript-documentation/61083ecc07cda5046e0e8b8b32736e908487ad2a/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React + Typescript documentation 2 | 3 | - prerequisities - TypeScript, React Fundamentals 4 | 5 | ## 1. Introduction to TypeScript 6 | 7 | - What is TypeScript? 8 | 9 | - programming language developed by microsoft 10 | - superset of JavaScript 11 | 12 | - Why TypeScript? 13 | 14 | - adds static typing to JavaScript 15 | - it helps to see bugs when writing codes; easy to find and fix bugs 16 | - gives auto suggestion 17 | - provides better documentation 18 | 19 | - Course outcomes 20 | - props types 21 | - built-in data type props 22 | - user defined data type props 23 | - events props 24 | - hooks types 25 | 26 | ## 2. Environment setup 27 | 28 | - install node & VSCode 29 | - install react+ts -> `npx create-react-app appName --template typescript` 30 | 31 | ## 3. typescript for Props - built in types 32 | 33 | - built in types example -> string, number, boolean 34 | - extension .ts and component extension is .tsx not .js or .jsx 35 | 36 | ```tsx 37 | // auto completion -> props. 38 | // if we pass anything other than string as name props we will get error 39 | // component props is an object 40 | // User.tsx (version-1) 41 | import React from "react"; 42 | const User = (props: { 43 | name: string; 44 | email: string; 45 | age: number; 46 | isRegistered: boolean; 47 | }) => { 48 | return ( 49 |
50 |

{props.name}

51 |

{props.email}

52 |

{props.age} years old

53 | {props.isRegistered ? ( 54 |

Registered Student

55 | ) : ( 56 |

Unregistered Student

57 | )} 58 |
59 | ); 60 | }; 61 | 62 | export default User; 63 | 64 | // User.tsx (version-2) 65 | import React from "react"; 66 | 67 | type UserProps = { 68 | name: string; 69 | email: string; 70 | age: number; 71 | isRegistered: boolean; 72 | }; 73 | const User = (props: UserProps) => { 74 | return ( 75 |
76 |

{props.name}

77 |

{props.email}

78 |

{props.age} years old

79 | {props.isRegistered ? ( 80 |

Registered Student

81 | ) : ( 82 |

Unregistered Student

83 | )} 84 |
85 | ); 86 | }; 87 | export default User; 88 | 89 | // User.tsx (version-3) 90 | import React from "react"; 91 | type UserProps = { 92 | name: string; 93 | email: string; 94 | age: number; 95 | isRegistered: boolean; 96 | }; 97 | const User = ({ name, email, age, isRegistered }: UserProps) => { 98 | return ( 99 |
100 |

{name}

101 |

{email}

102 |

{age} years old

103 | {isRegistered ?

Registered Student

:

Unregistered Student

} 104 |
105 | ); 106 | }; 107 | export default User; 108 | 109 | // App.tsx 110 | import React from "react"; 111 | import "./App.css"; 112 | import User from "./components/User"; 113 | 114 | function App() { 115 | return ( 116 |
117 |

User Management App

118 | 124 | 130 |
131 | ); 132 | } 133 | 134 | export default App; 135 | 136 | // void 137 | const handleClick = (): void => { 138 | console.log("clicked"); 139 | }; 140 | ``` 141 | 142 | ## 4. typescript for Props - User defined types 143 | 144 | - Object, Array, Union, enum, tuple, any, custom type 145 | 146 | - object props 147 | 148 | ```tsx 149 | import React from "react"; 150 | 151 | type UserProps = { 152 | user: { 153 | name: string; 154 | email: string; 155 | age: number; 156 | isRegistered: boolean; 157 | }; 158 | }; 159 | const User = ({ user }: UserProps) => { 160 | return ( 161 |
162 |

{user.name}

163 |

{user.email}

164 |

{user.age} years old

165 | {user.isRegistered ? ( 166 |

Registered Student

167 | ) : ( 168 |

Unregistered Student

169 | )} 170 |
171 | ); 172 | }; 173 | 174 | export default User; 175 | 176 | // App.tsx 177 | import React from "react"; 178 | import "./App.css"; 179 | import User from "./components/User"; 180 | 181 | const user1 = { 182 | name: "anisul islam", 183 | email: "anisul2010s@yahoo.co.uk", 184 | age: 32, 185 | isRegistered: true, 186 | }; 187 | const user2 = { 188 | name: "Rabeya Begum", 189 | email: "rabu2010s@yahoo.co.uk", 190 | age: 31, 191 | isRegistered: false, 192 | }; 193 | 194 | function App() { 195 | return ( 196 |
197 |

User Management App

198 | 199 | 200 |
201 | ); 202 | } 203 | 204 | export default App; 205 | 206 | // more updates for App.tsx 207 | import React from "react"; 208 | import "./App.css"; 209 | import User from "./components/User"; 210 | 211 | const users = [ 212 | { 213 | id: 1, 214 | name: "anisul islam", 215 | email: "anisul2010s@yahoo.co.uk", 216 | age: 32, 217 | isRegistered: true, 218 | }, 219 | { 220 | id: 2, 221 | name: "Rabeya Begum", 222 | email: "rabu2010s@yahoo.co.uk", 223 | age: 31, 224 | isRegistered: false, 225 | }, 226 | ]; 227 | 228 | function App() { 229 | return ( 230 |
231 |

User Management App

232 | {users.map((user) => ( 233 | 234 | ))} 235 |
236 | ); 237 | } 238 | 239 | export default App; 240 | ``` 241 | 242 | - array props 243 | 244 | ```tsx 245 | // simple example 246 | import React from "react"; 247 | 248 | type UserProps = { 249 | lang: string[]; 250 | }; 251 | const User = ({ lang }: UserProps) => { 252 | return ( 253 |
254 |

255 | Speaks:{" "} 256 | {lang.map((language, index) => { 257 | return {language} ; 258 | })} 259 |

260 |
261 | ); 262 | }; 263 | export default User; 264 | 265 | // App.tsx 266 | import React from "react"; 267 | import "./App.css"; 268 | import User from "./components/User"; 269 | function App() { 270 | return ( 271 |
272 |

User Management App

273 | 274 |
275 | ); 276 | } 277 | export default App; 278 | 279 | // complex example 280 | import React from "react"; 281 | 282 | type UserProps = { 283 | user: { 284 | name: string; 285 | email: string; 286 | age: number; 287 | isRegistered: boolean; 288 | languages: string[]; 289 | }; 290 | }; 291 | const User = ({ user }: UserProps) => { 292 | return ( 293 |
294 |

{user.name}

295 |

{user.email}

296 |

{user.age} years old

297 | {user.isRegistered ? ( 298 |

Registered Student

299 | ) : ( 300 |

Unregistered Student

301 | )} 302 |

303 | Speaks:{" "} 304 | {user.languages.map((language, index) => { 305 | return {language} ; 306 | })} 307 |

308 |
309 | ); 310 | }; 311 | export default User; 312 | 313 | // App.tsx 314 | import React from "react"; 315 | import "./App.css"; 316 | import User from "./components/User"; 317 | 318 | const users = [ 319 | { 320 | id: 1, 321 | name: "anisul islam", 322 | email: "anisul2010s@yahoo.co.uk", 323 | age: 32, 324 | isRegistered: true, 325 | languages: ["Bangla", "English"], 326 | }, 327 | { 328 | id: 2, 329 | name: "Rabeya Begum", 330 | email: "rabu2010s@yahoo.co.uk", 331 | age: 31, 332 | isRegistered: false, 333 | languages: ["Bangla", "English", "Finnish"], 334 | }, 335 | ]; 336 | 337 | function App() { 338 | return ( 339 |
340 |

User Management App

341 | {users.map((user) => ( 342 | 343 | ))} 344 |
345 | ); 346 | } 347 | export default App; 348 | 349 | // one more array example 350 | 351 | // App.tsx 352 | import React from "react"; 353 | import "./App.css"; 354 | import User from "./components/User"; 355 | const users = [ 356 | { 357 | id: 1, 358 | name: "anisul islam", 359 | email: "anisul2010s@yahoo.co.uk", 360 | }, 361 | { 362 | id: 2, 363 | name: "Rabeya Begum", 364 | email: "rabu2010s@yahoo.co.uk", 365 | }, 366 | ]; 367 | 368 | function App() { 369 | return ( 370 |
371 |

User Management App

372 | 373 |
374 | ); 375 | } 376 | export default App; 377 | 378 | // User.tsx 379 | import React from "react"; 380 | type UserProps = { 381 | users: { 382 | id: number; 383 | name: string; 384 | email: string; 385 | }[]; 386 | }; 387 | const User = ({ users }: UserProps) => { 388 | return ( 389 |
390 | {users.map((user) => { 391 | const { id, name, email } = user; 392 | return ( 393 |
394 |

{name}

395 |

{email}

396 |
397 | ); 398 | })} 399 |
400 | ); 401 | }; 402 | export default User; 403 | ``` 404 | 405 | - union of types 406 | 407 | ```tsx 408 | // Message.tsx 409 | import React from "react"; 410 | 411 | type MessageProps = { 412 | text: "ADD" | "UPDATE" | "DELETE"; 413 | }; 414 | 415 | const Message = (props: MessageProps) => { 416 | if (props.text === "ADD") { 417 | return

User is added

; 418 | } else if (props.text === "UPDATE") { 419 | return

User is updated

; 420 | } 421 | return

User is deleted

; 422 | }; 423 | 424 | export default Message; 425 | 426 | // App.tsx 427 | function App() { 428 | return ( 429 |
430 |

User Management App

431 | 432 | {/* */} 433 |
434 | ); 435 | } 436 | 437 | export default App; 438 | ``` 439 | 440 | - children props 441 | 442 | ```tsx 443 | // Card.tsx 444 | import React from "react"; 445 | type CardProps = { 446 | children: React.ReactNode; 447 | }; 448 | const Card = (props: CardProps) => { 449 | return
{props.children}
; 450 | }; 451 | 452 | export default Card; 453 | 454 | //User.tsx 455 | import React from "react"; 456 | import Card from "./Card"; 457 | 458 | type UserProps = { 459 | user: { 460 | name: string; 461 | email: string; 462 | age: number; 463 | isRegistered: boolean; 464 | languages: string[]; 465 | }; 466 | }; 467 | const User = ({ user }: UserProps) => { 468 | return ( 469 | 470 |

{user.name}

471 |

{user.email}

472 |

{user.age} years old

473 | {user.isRegistered ? ( 474 |

Registered Student

475 | ) : ( 476 |

Unregistered Student

477 | )} 478 |

479 | Speaks:{" "} 480 | {user.languages.map((language, index) => { 481 | return {language} ; 482 | })} 483 |

484 |
485 | ); 486 | }; 487 | export default User; 488 | ``` 489 | 490 | ## 5. Typing Event Props 491 | 492 | - example 493 | 494 | ```tsx 495 | // Typing event props 496 | click event: event: React.MouseEvent 497 | type ButtonProps = { 498 | handleClick: (event: React.MouseEvent) => void; 499 | handleChange: (event: React.ChangeEvent) => void 500 | }; 501 | 502 | //App.tsx 503 | import React, { useState } from "react"; 504 | 505 | type NewUserProps = { 506 | name: string; 507 | email: string; 508 | }; 509 | const NewUser = () => { 510 | const [user, setUser] = useState({ name: "", email: "" }); 511 | 512 | const handleChange = (event: React.ChangeEvent) => { 513 | const fieldName = event.target.name; 514 | setUser({ ...user, [fieldName]: event.target.value }); 515 | }; 516 | 517 | const handleSubmit = (event: React.FormEvent) => { 518 | event.preventDefault(); 519 | console.log(user); 520 | }; 521 | 522 | 523 | const handleSubmit = (event: FormEvent) => { 524 | event.preventDefault(); 525 | const newTodo = { id: Math.random().toString(), title }; 526 | onAddNewTodo(newTodo); 527 | 528 | // const target = event.target as typeof event.target & { 529 | // title: { value: string }; 530 | // }; 531 | // console.log(target.title.value); 532 | }; 533 | return ( 534 |
535 |

Create User

536 |
537 |
538 | 549 |
550 |
551 | 562 |
563 | 564 |
565 |
566 | ); 567 | }; 568 | 569 | export default NewUser; 570 | 571 | ``` 572 | 573 | ## 6. Style Props 574 | 575 | - example 576 | 577 | ```tsx 578 | // props for styles -> React.CSSProperties 579 | import React from "react"; 580 | 581 | type ButtonProps = { 582 | styles: React.CSSProperties; 583 | }; 584 | 585 | const Button = (props: ButtonProps) => { 586 | return ; 587 | }; 588 | 589 | export default Button; 590 | 591 | import "./App.css"; 592 | import Button from "./components/Button"; 593 | 594 | function App() { 595 | return ( 596 |
597 |
601 | ); 602 | } 603 | 604 | export default App; 605 | ``` 606 | 607 | ## 7. Typing useState Hooks 608 | 609 | - example 610 | 611 | ```tsx 612 | import React, { useState } from "react"; 613 | import "./App.css"; 614 | 615 | const App = () => { 616 | // type is automatically infereed as number 617 | const [count, setCount] = useState(0); 618 | 619 | const handleIncrement = (): void => { 620 | setCount((count) => count + 1); 621 | }; 622 | 623 | const handleDecrement = (): void => { 624 | setCount((count) => count - 1); 625 | }; 626 | 627 | return ( 628 |
629 |

Count : {count}

630 | 631 | 632 |
633 | ); 634 | }; 635 | 636 | export default App; 637 | 638 | // dealing with future values in useState Hook 639 | import React, { useState } from "react"; 640 | import "./App.css"; 641 | 642 | type User = { 643 | id: number; 644 | name: string; 645 | }; 646 | 647 | const App = () => { 648 | // const [data, setData] = useState(null); 649 | const [data, setData] = useState(null); 650 | 651 | const handleSetData = () => { 652 | // setData("Anisul islam"); 653 | setData({ id: 101, name: "anisul islam" }); 654 | console.log(data); 655 | }; 656 | 657 | return ( 658 |
659 |

UseState Future value

660 | 661 | {/* {data &&

{data}

} */} 662 | 663 | 664 |
665 | ); 666 | }; 667 | 668 | export default App; 669 | 670 | // type asertion - without optional chaining operator 671 | import React, { useState } from "react"; 672 | import "./App.css"; 673 | 674 | type User = { 675 | id: number; 676 | name: string; 677 | }; 678 | 679 | const App = () => { 680 | // const [data, setData] = useState(null); 681 | const [data, setData] = useState({} as User); 682 | 683 | const handleSetData = () => { 684 | // setData("Anisul islam"); 685 | setData({ id: 101, name: "anisul islam" }); 686 | console.log(data); 687 | }; 688 | 689 | return ( 690 |
691 |

UseState Future value

692 | 693 | {/* {data &&

{data}

} */} 694 |

{data.id}

695 |

{data.name}

696 |
697 | ); 698 | }; 699 | 700 | export default App; 701 | ``` 702 | 703 | ## 8. Typing useReducer Hooks 704 | 705 | - example 706 | 707 | ```tsx 708 | // Counter.tsx 709 | import React, { useReducer } from "react"; 710 | 711 | const INCREMENT = "INCREMENT"; 712 | const INCREMENTBYAMOUNT = "INCREMENTBYAMOUNT"; 713 | const RESET = "RESET"; 714 | const DECREMENT = "DECREMENT"; 715 | 716 | const initialState = { count: 0 }; 717 | type counterState = { 718 | count: number; 719 | }; 720 | 721 | type IncrementActionType = { type: typeof INCREMENT }; 722 | type IncrementByAmountActionType = { 723 | type: typeof INCREMENTBYAMOUNT; 724 | payload: number; 725 | }; 726 | type ResetActionType = { type: typeof RESET }; 727 | type DecrementActionType = { type: typeof DECREMENT }; 728 | 729 | type counterActionType = 730 | | IncrementActionType 731 | | DecrementActionType 732 | | ResetActionType 733 | | IncrementByAmountActionType; 734 | 735 | const reducer = (state: counterState, action: counterActionType) => { 736 | switch (action.type) { 737 | case INCREMENT: 738 | return { count: state.count + 1 }; 739 | case INCREMENTBYAMOUNT: 740 | return { count: state.count + action.payload }; 741 | case RESET: 742 | return { count: 0 }; 743 | case DECREMENT: 744 | return { count: state.count - 1 }; 745 | default: 746 | throw new Error(); 747 | } 748 | }; 749 | 750 | const Counter = () => { 751 | const [state, dispatch] = useReducer(reducer, initialState); 752 | return ( 753 |
754 |

Count : {state.count}

755 | 762 | 769 | 776 | 783 |
784 | ); 785 | }; 786 | 787 | export default Counter; 788 | ``` 789 | --------------------------------------------------------------------------------