paint-brush
Cách di chuyển dự án React từ JavaScript sang TypeScripttừ tác giả@leandronnz
7,489 lượt đọc
7,489 lượt đọc

Cách di chuyển dự án React từ JavaScript sang TypeScript

từ tác giả Leandro Nuñez24m2023/10/19
Read on Terminal Reader

dài quá đọc không nổi

Di chuyển dự án React từ Javascript sang TypeScript không chỉ là 'tìm kiếm và thay thế' các tệp .js bằng .tsx. Đó là một bước đi chiến lược bao gồm việc học các quy ước mới, hiểu sâu các loại và quan trọng nhất là thay đổi cách chúng ta nghĩ về độ tin cậy và tính nhất quán của mã. Dưới đây là một vài lưu ý: Mạng lưới an toàn: TypeScript đã giới thiệu một lớp an toàn cho dự án của chúng tôi, phát hiện lỗi trước khi chúng tàn phá trong thời gian chạy. Mạng lưới an toàn này, khi bạn đã quen với nó, sẽ là yếu tố thay đổi cuộc chơi về độ tin cậy đối với mã của bạn và tốc độ phát triển tổng thể. Giao tiếp rõ ràng hơn: Với các loại, mã của chúng tôi hiện giao tiếp rõ ràng hơn. Cho dù bạn đang xem lại mã của mình hay một thành viên mới trong nhóm đang cố gắng hiểu cấu trúc thành phần của bạn, TypeScript sẽ đóng vai trò như một lớp tài liệu bổ sung. Niềm tin tái cấu trúc: Bạn sợ tái cấu trúc? Chà, TypeScript luôn hỗ trợ bạn. Với các loại đảm bảo hợp đồng trong mã của bạn, nhiều lỗi tiềm ẩn sẽ được phát hiện trong các giai đoạn tái cấu trúc, giúp quá trình này bớt khó khăn hơn. Cộng đồng và Hệ sinh thái: Sử dụng TypeScript mở ra cánh cửa cho một hệ sinh thái thịnh vượng. Từ các thư viện đã nhập trên DefiniteTyped đến sự hỗ trợ vô tận trên các diễn đàn cộng đồng và tích hợp gói bên thứ ba hợp lý hơn, bạn đang ở trong một công ty tốt. Đường cong học tập: Có, TypeScript giới thiệu một đường cong học tập. Có lẽ đã có những khoảnh khắc thất vọng, nhầm lẫn về các loại và giao diện hoặc vật lộn với trình biên dịch. Tuy nhiên, hãy nhìn lại hành trình của bạn và bạn sẽ thấy hiện tại bạn hiểu mã của mình và hành vi của nó nhiều hơn đến mức nào.
featured image - Cách di chuyển dự án React từ JavaScript sang TypeScript
Leandro Nuñez HackerNoon profile picture
0-item


Mục lục

  • Giới thiệu

  • Tại sao phải di cư? Hiểu lợi ích

  • Trước khi bạn bắt đầu: Điều kiện tiên quyết

  • Bắt đầu di chuyển: Thiết lập TypeScript trong dự án của bạn

  • Tái cấu trúc các thành phần React

  • API bối cảnh và quản lý trạng thái

  • Hoạt động định tuyến và không đồng bộ

  • Kiểm tra trong TypeScript

  • Xử lý các gói không phải TypeScript

  • Thực tiễn tốt nhất và những cạm bẫy phổ biến

  • Phần kết luận

  • Tài nguyên bổ sung



Giới thiệu

Xin chào các nhà phát triển đồng nghiệp! Thật thú vị khi được gặp bạn ở đây, sẵn sàng khám phá quá trình chuyển đổi từ JavaScript sang TypeScript trong các dự án React của chúng tôi.


Bây giờ, nếu bạn đã từng làm việc với JavaScript, bạn sẽ biết nó giống như một đôi giày cũ, thoải mái - hơi mòn, đôi khi không thể đoán trước được nhưng quen thuộc. Tuy nhiên, TypeScript giống như nâng cấp giày với đế lót tùy chỉnh; đó là trải nghiệm đi bộ tương tự nhưng có thêm sự hỗ trợ.


Vì vậy, tất cả những tin đồn về TypeScript là gì?


Chà, về cơ bản nó là JavaScript nhưng có rất nhiều khả năng bổ sung được đưa vào, tính năng quan trọng nhất là kiểm tra kiểu.


Hãy tưởng tượng việc mã hóa mà không có những lỗi undefined is not a function xuất hiện bất ngờ. Đó chính là sự bình yên mà TypeScript mang đến cho cuộc sống của bạn.


Trong hướng dẫn này, chúng ta sẽ tìm hiểu lý do và cách tích hợp TypeScript vào dự án React của bạn.


Tại sao lại phản ứng? Bởi vì nó tuyệt vời và rõ ràng là chúng tôi yêu thích nó. Ngoài ra, việc kết hợp cách tiếp cận dựa trên thành phần của React với các tính năng kiểm tra kiểu của TypeScript sẽ mang lại trải nghiệm mã hóa thú vị và hiệu quả nghiêm túc.


Dưới đây là một cái nhìn sơ lược về việc thêm TypeScript vào một dự án sẽ như thế nào. Trong một thành phần JavaScript điển hình, bạn sẽ có:

 // JavaScript way function Greeting({ name }) { return <h1>Hello, {name}</h1>; }


Với TypeScript, chúng tôi đang giới thiệu một cách để đảm bảo name luôn được coi là một chuỗi:

 // TypeScript style type Props = { name: string; }; function Greeting({ name }: Props) { return <h1>Hello, {name}</h1>; }


Bạn có để ý phần type Props không ?


Đó là cách nói của TypeScript, "Này, tôi đang xem; tốt hơn hãy đảm bảo name là một chuỗi!" Đó là một sự thay đổi đơn giản nhưng có ý nghĩa sâu sắc. Giờ đây, bạn đã có một thiên thần hộ mệnh tích cực ngăn chặn các lỗi liên quan đến loại, giúp mã của bạn trở nên mạnh mẽ và dễ đoán hơn.


Nhưng đó chỉ là một cái nhìn thoáng qua nhỏ. Có cả thế giới lợi ích và cách thực hành với TypeScript mà chúng tôi sẽ giải thích trong hướng dẫn toàn diện này. Từ việc thiết lập môi trường của bạn đến việc tái cấu trúc các thành phần và đạo cụ, thậm chí cả các phương pháp hay nhất để tránh những cạm bẫy phổ biến, chúng tôi có rất nhiều điều cần đề cập. Vì vậy, hãy thắt dây an toàn và bắt đầu chương trình này!




Tại sao phải di cư? Hiểu lợi ích

Nếu bạn đang dự tính chuyển từ JavaScript sang TypeScript, đặc biệt là trong các dự án React của mình, bạn không đơn độc thắc mắc "Liệu nó có thực sự đáng để bạn gặp rắc rối không?" Việc chuyển đổi ngôn ngữ của toàn bộ dự án không phải là một việc nhỏ; nó đòi hỏi nỗ lực, học hỏi và ban đầu là năng suất bị chậm lại một chút. Vậy tại sao các nhà phát triển lại thực hiện chuyển đổi? Hãy chia nhỏ những lý do thuyết phục.


1. Phát hiện lỗi sớm hơn: Kiểm tra loại tĩnh

Tính năng cốt lõi của TypeScript là hệ thống kiểu tĩnh. Không giống như JavaScript, được gõ động, TypeScript cho phép bạn chỉ định loại cho biến, tham số hàm và giá trị trả về. Lợi ích là gì? Lỗi được phát hiện trong quá trình phát triển, rất lâu trước khi mã được đưa vào sản xuất.


Hãy xem xét một ví dụ đơn giản:

 // In JavaScript function createGreeting(name) { return `Hello, ${name}`; } // You might not catch this typo until runtime const greeting = createGreeting(123); console.log(greeting); // "Hello, 123" - Wait, that's not right!


Bây giờ, hãy xem TypeScript giúp ích như thế nào:

 // In TypeScript function createGreeting(name: string): string { return `Hello, ${name}`; } // TypeScript will flag this immediately - '123' is not a string! const greeting = createGreeting(123);


Với TypeScript, lỗi trông có vẻ vô hại đó sẽ bị phát hiện ngay lập tức, đảm bảo rằng bạn nhận thức được sự cố ngay khi nó xảy ra. Bằng cách này, vòng phản hồi được rút ngắn và bạn không phải gãi đầu khi nhìn thấy những lỗi lạ trong môi trường sản xuất của mình.


2. Cải thiện chất lượng mã và tính dễ hiểu

Việc thực thi gõ của TypeScript có nghĩa là bất kỳ nhà phát triển nào khác (hoặc thậm chí là bạn trong tương lai) đều có thể hiểu nhanh loại dữ liệu mà một hàm mong đợi và nó trả về những gì. Sự rõ ràng này làm cho cơ sở mã dễ đọc hơn và tự ghi lại tài liệu hơn.


Hãy tưởng tượng bạn bắt gặp một hàm JavaScript được viết bởi một đồng nghiệp:

 function calculateTotal(items) { // ... complicated logic ... }


Có thể bạn sẽ cần phải tìm hiểu kỹ về hàm này hoặc tìm xem nó được sử dụng ở đâu để hiểu items nào nên có. Với TypeScript, mọi chuyện sẽ rõ ràng ngay lập tức:

 type Item = { price: number; quantity: number; }; // Now we know exactly what to expect! function calculateTotal(items: Item[]): number { // ... complicated logic ... }


3. Hỗ trợ trình soạn thảo nâng cao

TypeScript đưa trải nghiệm của nhà phát triển lên một tầm cao mới bằng cách nâng cao trình soạn thảo văn bản và IDE với khả năng tự động hoàn thành, tái cấu trúc và gỡ lỗi được cải thiện. Việc tích hợp này có thể thực hiện được vì TypeScript có thể chia sẻ hiểu biết về mã của bạn với trình soạn thảo của bạn.

Bạn sẽ gặp phải điều này khi thấy trình soạn thảo của mình đề xuất tên phương thức, cung cấp thông tin tham số hàm hoặc cảnh báo bạn về việc sử dụng hàm không chính xác. Nó giống như có một người điều khiển phụ giúp điều hướng qua mã với một lớp an toàn bổ sung.


4. Cộng tác dễ dàng hơn

Trong môi trường nhóm, TypeScript tỏa sáng bằng cách giúp thực thi các tiêu chuẩn và cấu trúc nhất định trên cơ sở mã. Khi nhiều nhà phát triển đóng góp cho một dự án, các quy tắc nghiêm ngặt của TypeScript đảm bảo mọi người đều tuân thủ các nguyên tắc viết mã giống nhau, giúp việc cộng tác trở nên suôn sẻ hơn. Đó là ngôn ngữ chung nói lên 'chất lượng và tính nhất quán' trên mọi phương diện.


5. Chứng minh mã của bạn trong tương lai

JavaScript đang phát triển và TypeScript nhằm mục đích theo kịp các tính năng mới nhất. Bằng cách sử dụng TypeScript, bạn có thể bắt đầu tận dụng thế hệ tính năng JavaScript tiếp theo trước khi chúng được áp dụng phổ biến, đảm bảo dự án của bạn luôn hiện đại và tiên tiến.


Tóm lại, việc chuyển sang TypeScript không chỉ là phát hiện lỗi sớm hơn; đó là về sự cải thiện toàn diện quá trình mã hóa của bạn. Từ việc cộng tác nhóm tốt hơn đến việc kiểm chứng các dự án của bạn trong tương lai, TypeScript cung cấp nền tảng vững chắc để xây dựng các ứng dụng đáng tin cậy, có thể mở rộng và có thể bảo trì.


Việc chuyển đổi ban đầu có vẻ khó khăn, nhưng với những lợi ích nêu trên, rõ ràng tại sao TypeScript lại trở thành lựa chọn yêu thích của nhiều nhà phát triển trên toàn thế giới. Sẵn sàng để đi sâu vào? Hãy tiếp tục!



Trước khi bạn bắt đầu: Điều kiện tiên quyết

Được rồi, vậy bạn đã sẵn sàng chuyển sang TypeScript với dự án React của mình chưa? Quyết định tuyệt vời!


Nhưng trước khi đi sâu vào quy trình thực tế, chúng ta cần đảm bảo một số điều đã được thực hiện.

Hãy xem đây là giai đoạn chuẩn bị của chúng tôi, nơi chúng tôi chuẩn bị sẵn sàng tất cả các công cụ để quá trình chuyển đổi diễn ra suôn sẻ như bơ.


Đây là những gì bạn cần chuẩn bị sẵn:

1. Dự án React hiện có

Trước tiên, bạn cần có một dự án React hiện có. Dự án này phải là dự án mà bạn cảm thấy thoải mái khi thử nghiệm; mặc dù quá trình di chuyển khá đơn giản nhưng bạn sẽ muốn thực hiện việc này trong một không gian nơi có thể tạo ra tình trạng lộn xộn tạm thời.


 // Here's a simple React functional component in your project export default function Greeting({ name }) { return <h1>Hello, {name}!</h1>; }


Thành phần này là một điểm khởi đầu tốt - nó hoạt động tốt, sạch sẽ và chúng ta có thể thấy nhanh những gì đang diễn ra.

2. Hiểu biết cơ bản về TypeScript

Bạn không cần phải là một chuyên gia về TypeScript, nhưng việc hiểu những điều cơ bản sẽ giúp quá trình chuyển đổi này dễ dàng hơn rất nhiều.


Biết cách xác định các loại, giao diện và biết sự khác biệt giữa typeinterface .

Một chút bài tập về nhà sẽ giúp ích rất nhiều, hãy tin tôi đi.


 // A sneak peek into TypeScript syntax type Props = { name: string; // defining the 'name' expected to be a string }; // Your component in TypeScript would look like this import React, { FC } from 'react'; interface GreetingProps { name: string; } const Greeting: FC<GreetingProps> = ({ name }) => { return <h1>Hello, {name}!</h1>; } export default Greeting;


Thấy sự khác biệt? Hiện tại, chúng tôi đang nói rõ về những gì Greeting mong đợi, giúp thành phần của chúng tôi dễ dự đoán hơn và dễ làm việc hơn.


3. Nút và NPM/Sợi

Môi trường phát triển của bạn phải được cài đặt Node.js vì chúng tôi sẽ sử dụng npm hoặc yarn để xử lý các gói của mình. Yêu cầu này được đưa ra vì bạn đang làm việc với React, nhưng việc đảm bảo chắc chắn sẽ không có hại gì, phải không?


 # Check if Node is installed node --version # Check if npm is installed npm --version # Or for yarn yarn --version


Thiết bị đầu cuối của bạn sẽ hiển thị cho bạn phiên bản hiện tại của những công cụ này, xác nhận rằng tất cả chúng đã được thiết lập và sẵn sàng hoạt động.


4. Trình chỉnh sửa mã

Bạn sẽ cần một trình soạn thảo mã có thể xử lý tốt TypeScript. Visual Studio Code được nhiều người yêu thích vì nó tích hợp sẵn hỗ trợ TypeScript mạnh mẽ, giúp quá trình phát triển mượt mà hơn với khả năng hoàn thành mã thông minh và đánh dấu lỗi.


5. Kiểm soát phiên bản

Bước này không bắt buộc nhưng là một bước thông minh. Đảm bảo dự án hiện tại của bạn được kiểm soát phiên bản bằng git. Nếu có điều gì đó không ổn (mặc dù chúng tôi sẽ cố gắng đảm bảo điều đó không xảy ra), bạn luôn có thể quay lại phiên bản trước mà không bị mất ngủ.


 # Check if git is installed git --version # If not, you need to initialize version control before proceeding git init git add . git commit -m "Pre-TypeScript commit"


Có mạng lưới an toàn này có nghĩa là bạn có thể tự tin thử nghiệm và biết rằng lưng của bạn được bảo vệ.


Đó là về điều kiện tiên quyết của chúng tôi! Bạn đã có dự án, đã hoàn thiện một số TypeScript, môi trường của bạn đã sẵn sàng và mạng lưới an toàn của bạn đã sẵn sàng.


Bây giờ, tất cả chúng ta đã sẵn sàng đi sâu vào quá trình di chuyển. Hãy để quả bóng lăn!



Bắt đầu di chuyển: Thiết lập TypeScript trong dự án của bạn Tái cấu trúc các thành phần React

Được rồi, sang giai đoạn tiếp theo!


Chúng ta đã bắt đầu với TypeScript, nhưng bây giờ chúng ta phải bắt tay vào thực hiện.


Đã đến lúc cấu trúc lại các thành phần React của chúng ta. Bước này không chỉ liên quan đến việc thay đổi phần mở rộng tệp; chúng tôi cần cập nhật mã thành phần của mình để sử dụng các tính năng của TypeScript nhằm mang lại trải nghiệm mã hóa mạnh mẽ hơn, không có lỗi.

Hãy đi sâu vào!


1. Thay đổi phần mở rộng tệp

Trước tiên, hãy đổi tên các tệp thành phần của chúng ta. Quá trình này bao gồm việc thay đổi phần mở rộng từ .js thành .tsx cho các tệp chứa mã JSX.


Đây là cách bạn có thể thực hiện việc này hàng loạt trong thư mục nguồn của dự án từ dòng lệnh:

 # For Unix-like shells, navigate to your source folder and run: find . -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.tsx"' {} \; # If you're using PowerShell (Windows), navigate to your source folder and run: Get-ChildItem -Filter *.js -Recurse | Rename-Item -NewName { $_.Name -replace '\.js$','.tsx' }


Các lệnh này tìm kiếm tất cả các tệp .js trong thư mục nguồn của dự án của bạn và đổi tên chúng thành .tsx . Nó giống như nói với các tập tin của bạn rằng "Chào mừng đến với thế giới TypeScript!"


2. Nhập các thành phần của bạn

Với các tệp của chúng tôi đã được đổi tên, hãy xử lý mã. Chúng ta sẽ bắt đầu với một thành phần chức năng đơn giản trong JavaScript:

 // Before: MyComponent.js import React from 'react'; function MyComponent({ greeting }) { return <h1>{greeting}, world!</h1>; }


Bây giờ, hãy cấu trúc lại cái này để sử dụng TypeScript:

 // After: MyComponent.tsx import React, { FC } from 'react'; // Define a type for the component props interface MyComponentProps { greeting: string; } // Use the 'FC' (Functional Component) generic from React, with our props type const MyComponent: FC<MyComponentProps> = ({ greeting }) => { return <h1>{greeting}, world!</h1>; }


Chúng ta đã làm gì ở đây?


Chúng tôi đã xác định giao diện MyComponentProps để mô tả các props của thành phần, đảm bảo an toàn về kiểu. Bằng cách nói lời greeting là một chuỗi, TypeScript sẽ hét vào mặt chúng ta nếu thay vào đó chúng ta cố gắng chuyển một số. Chúng tôi cũng sử dụng loại FC (viết tắt của Functional Component ) từ định nghĩa loại của React, đảm bảo rằng TypeScript biết đó là thành phần React.


3. Gõ mạnh useState và useEffect

Hãy nâng cấp hơn nữa các thành phần của chúng ta bằng cách thêm các loại vào trạng thái và hiệu ứng, các tính năng chung của các thành phần chức năng.


Đây là một thành phần có trạng thái và hiệu ứng:

 // Before: Counter.js import React, { useState, useEffect } from 'react'; function Counter() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }


Hãy rắc một số phép thuật TypeScript vào đây:

 // After: Counter.tsx import React, { useState, useEffect, FC } from 'react'; const Counter: FC = () => { // Declare the 'count' state variable with TypeScript const [count, setCount] = useState<number>(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(prevCount => prevCount + 1)}> Click me </button> </div> ); }


Trong thành phần được tái cấu trúc của chúng tôi, chúng tôi đã yêu cầu TypeScript rõ ràng phải mong đợi một number cho trạng thái count của chúng tôi.


Chi tiết này ngăn ngừa các lỗi phiền toái mà chúng ta có thể vô tình nhận được một chuỗi, đối tượng hoặc trời cấm, null thay vì con số mong đợi của chúng ta.


Và chúng ta bắt đầu!


Chúng tôi đã tái cấu trúc thành công các thành phần React để sử dụng TypeScript. Bằng cách nhập rõ ràng các thành phần, trạng thái và đạo cụ, chúng tôi đang tạo ra một cơ sở mã dễ dự đoán và dễ bảo trì hơn. Chúng tôi không chỉ viết mã; chúng tôi đang tạo ra một kiệt tác với độ chính xác xứng đáng.


Tiếp theo, chúng ta sẽ tìm hiểu sâu hơn về các tình huống phức tạp hơn và cách TypeScript giải cứu chúng ta!



API bối cảnh và quản lý trạng thái

Bây giờ, hãy cùng tìm hiểu chi tiết về quản lý trạng thái trong React với TypeScript. Nếu bạn đã sử dụng API ngữ cảnh trong dự án JavaScript, bạn sẽ biết đây là một tính năng mạnh mẽ để truyền dữ liệu qua cây thành phần mà không cần phải truyền đạo cụ xuống theo cách thủ công ở mọi cấp độ. Trong TypeScript, chúng ta nhận được lợi ích bổ sung của việc nhập dữ liệu nghiêm ngặt, điều này làm cho dữ liệu ngữ cảnh của chúng ta trở nên mạnh mẽ hơn và dễ đoán hơn.


Sẵn sàng để nhảy vào? Đi nào!


1. Tạo bối cảnh đánh máy

Đầu tiên, chúng ta sẽ tạo một bối cảnh mới với TypeScript. Ngữ cảnh này sẽ đảm bảo rằng mọi giá trị mặc định, giá trị của nhà cung cấp hoặc thành phần người tiêu dùng đều khớp với loại dự kiến của chúng tôi.


Đây là cách bạn xác định ngữ cảnh cơ bản trong JavaScript:

 // Before: DataContext.js import React, { createContext, useState } from 'react'; export const DataContext = createContext(); export const DataProvider = ({ children }) => { const [data, setData] = useState(null); return ( <DataContext.Provider value={{ data, setData }}> {children} </DataContext.Provider> ); };


Bây giờ, hãy nhập ngữ cảnh này bằng TypeScript:

 // After: DataContext.tsx import React, { createContext, useState, FC, ReactNode } from 'react'; // First, we define a type for our context's state interface DataContextState { data: any; // Tip: Replace 'any' with the expected type of 'data' setData: (data: any) => void; // And here too, replace 'any' with the actual expected type } // We ensure our createContext() call is typed with the above interface export const DataContext = createContext<DataContextState | undefined>(undefined); // Now, let's create a provider component export const DataProvider: FC<{children: ReactNode}> = ({ children }) => { const [data, setData] = useState<any>(null); // Again, consider replacing 'any' with your actual data type // The context provider now expects a value that matches 'DataContextState' return ( <DataContext.Provider value={{ data, setData }}> {children} </DataContext.Provider> ); };


Những gì chúng tôi đã làm ở đây là tạo một giao diện TypeScript, DataContextState , để nhập dữ liệu ngữ cảnh của chúng tôi một cách nghiêm ngặt. Chúng tôi cũng đã nhập hàm createContext và thành phần DataProvider để đảm bảo rằng mọi thứ từ biến trạng thái đến giá trị ngữ cảnh đều phù hợp với các loại đã xác định của chúng tôi.


2. Sử dụng ngữ cảnh đã nhập

Bây giờ chúng ta đã gõ DataContext , hãy xem cách chúng ta có thể sử dụng nó trong một thành phần.


Chúng ta sẽ cần sử dụng hook useContext và đây là cách thực hiện:

 // ComponentUsingContext.tsx import React, { useContext, FC } from 'react'; import { DataContext } from './DataContext'; const ComponentUsingContext: FC = () => { // Here we're telling TypeScript to expect 'DataContextState' from our context const { data, setData } = useContext(DataContext) ?? {}; // This function would update the context state, triggering re-renders in consuming components const handleUpdateData = () => { const newData = { message: "Hello, TypeScript!" }; // This should match the structure of your data type setData(newData); }; return ( <div> <pre>{JSON.stringify(data, null, 2)}</pre> <button onClick={handleUpdateData}>Update Data</button> </div> ); };


Trong ComponentUsingContext , chúng tôi đang truy cập vào ngữ cảnh và mong đợi TypeScript xác thực rằng giá trị phù hợp với DataContextState . Hàm handleUpdateData của chúng tôi minh họa cách bạn có thể cập nhật trạng thái chia sẻ—bất kỳ thành phần nào sử dụng DataContext sẽ hiển thị lại với dữ liệu mới khi setData được gọi.


Bằng cách sử dụng TypeScript với API ngữ cảnh, chúng tôi tin tưởng rằng việc quản lý trạng thái được chia sẻ của chúng tôi nhất quán trên toàn bộ ứng dụng. Trình biên dịch nắm bắt mọi khác biệt giữa những gì ngữ cảnh của chúng tôi cung cấp và những gì các thành phần của chúng tôi mong đợi. Sức mạnh tổng hợp này làm cho mã của chúng tôi đáng tin cậy hơn và quá trình phát triển của chúng tôi mượt mà hơn, cho phép chúng tôi tránh được toàn bộ các loại lỗi mà chúng tôi có thể gặp phải.


Hãy tiếp tục làm tốt công việc của mình và hãy nhớ rằng, chỉ cần gõ một chút là bạn sẽ tiết kiệm được rất nhiều lần sửa lỗi sau này!



Kiểm tra hoạt động định tuyến và không đồng bộ trong TypeScript >

Bây giờ chúng ta đã thấy cách TypeScript cải thiện các khía cạnh khác nhau của ứng dụng React, đã đến lúc nói về một lĩnh vực quan trọng khác: thử nghiệm.


Kiểm tra là cơ bản để đảm bảo ứng dụng của chúng tôi hoạt động như mong đợi và TypeScript có thể làm cho các thử nghiệm của chúng tôi đáng tin cậy và hiệu quả hơn. Hãy cùng tìm hiểu xem TypeScript đóng vai trò như thế nào trong việc thử nghiệm, đặc biệt là trong dự án React.


1. Thiết lập giai đoạn thử nghiệm

Trước khi chúng tôi nhập mã, hãy đảm bảo bạn đã cài đặt các thư viện cần thiết để thử nghiệm trong dự án React. Dưới đây là thiết lập nhanh với Thư viện thử nghiệm Jest và React, được sử dụng rộng rãi cùng nhau để thử nghiệm các ứng dụng React:

 npm install --save-dev jest @types/jest @testing-library/react @testing-library/jest-dom


Các thư viện này cung cấp một môi trường mạnh mẽ để viết các bài kiểm tra đơn vị và tích hợp. Bây giờ, hãy xem xét một kịch bản trong thế giới thực để rõ ràng.


2. Kịch bản thử nghiệm trong thế giới thực: Thành phần lời chào của người dùng

Hãy tưởng tượng chúng ta có một thành phần đơn giản trong ứng dụng chào đón người dùng dựa trên thời gian trong ngày. Đó là một thành phần chức năng lấy tên người dùng làm chỗ dựa và thời gian hiện tại làm trạng thái.


Đây là thành phần UserGreeting của chúng tôi có thể trông như thế nào:

 // UserGreeting.tsx import React, { FC, useState, useEffect } from 'react'; interface UserGreetingProps { name: string; } const UserGreeting: FC<UserGreetingProps> = ({ name }) => { const [currentHour, setCurrentHour] = useState(new Date().getHours()); const [greeting, setGreeting] = useState(''); useEffect(() => { // Determine the time of day and set the appropriate greeting if (currentHour < 12) { setGreeting('Good morning'); } else if (currentHour < 18) { setGreeting('Good afternoon'); } else { setGreeting('Good evening'); } }, [currentHour]); return ( <div> <h1>{greeting}, {name}!</h1> </div> ); } export default UserGreeting;


Bây giờ, chúng ta cần viết các bài kiểm thử để đảm bảo thành phần của chúng ta hoạt động như mong đợi trong các điều kiện khác nhau. Các trường hợp thử nghiệm của chúng tôi sẽ xác nhận rằng lời chào thích hợp được hiển thị dựa trên thời gian trong ngày.


Đây là cách chúng ta có thể viết các bài kiểm tra này bằng Thư viện kiểm tra Jest và React:

 // UserGreeting.test.tsx import React from 'react'; import { render, screen } from '@testing-library/react'; import UserGreeting from './UserGreeting'; describe('UserGreeting Component', () => { // Mock date for consistent testing const originalDate = Date; beforeAll(() => { const mockDate = new Date(2023, 10, 17, 14); // 2:00 PM global.Date = jest.fn(() => mockDate) as any; }); afterAll(() => { global.Date = originalDate; // Restore original Date object }); it('displays the correct greeting for the afternoon', () => { render(<UserGreeting name="Jordan" />); // Assert the greeting based on the mocked time of day expect(screen.getByText('Good afternoon, Jordan!')).toBeInTheDocument(); }); // Additional tests would repeat this process for other times of day, // ensuring our component behaves consistently. });


Trong tập lệnh này, chúng tôi đang hiển thị thành phần của mình với thời gian đã đặt (giả định là 2:00 chiều) và kiểm tra xem nó có tạo ra "Chào buổi chiều" như mong đợi hay không. Chúng tôi có thể viết thêm bài kiểm tra vào các thời điểm khác trong ngày (sáng, tối) để đảm bảo thành phần của chúng tôi được bao phủ đầy đủ.


Thông qua TypeScript, chúng tôi đảm bảo rằng các đạo cụ mà chúng tôi chuyển đến các thành phần trong các thử nghiệm của mình khớp với các loại dự kiến. Bằng cách này, chúng tôi tránh gặp phải các vấn đề với đạo cụ không chính xác có thể dẫn đến kết quả âm tính giả trong các thử nghiệm của chúng tôi, đảm bảo rằng các thử nghiệm của chúng tôi mạnh mẽ và đáng tin cậy.


Sử dụng TypeScript trong thử nghiệm giúp phát hiện sớm các vấn đề trong quá trình phát triển, giúp ứng dụng của chúng tôi mạnh mẽ hơn và dễ bảo trì hơn. Đó là một tình huống đôi bên cùng có lợi! Hãy nhớ rằng, thử nghiệm nhất quán và toàn diện là dấu hiệu của sự phát triển phần mềm chất lượng cao. Giữ nó lên!




Xử lý các gói không phải TypeScript

Được rồi, hãy giải quyết một lĩnh vực thường khiến mọi người bối rối khi chuyển sang TypeScript trong dự án React: xử lý các thư viện và gói JavaScript không được viết bằng TypeScript. Đó là một kịch bản phổ biến; bạn đã thiết lập và chạy dự án TypeScript của mình, sau đó bạn cài đặt gói của bên thứ ba, chỉ để thấy trình biên dịch TypeScript của bạn phàn nàn. Đừng lo lắng; có những giải pháp.


1. Gặp phải vấn đề

Đây là một tình huống điển hình: bạn đang cố gắng sử dụng một gói không có hỗ trợ TypeScript ngay lập tức và trình biên dịch TypeScript bắt đầu đưa ra các lỗi như "Không thể tìm thấy tệp khai báo cho 'tên mô-đun'." Nghe có vẻ quen?


Vấn đề này phát sinh do TypeScript dựa vào định nghĩa kiểu để hiểu cấu trúc của thư viện và gói. Nếu những định nghĩa kiểu này bị thiếu, TypeScript sẽ bị mất một chút. Nhưng đừng lo, chúng tôi có chiến lược để giải quyết vấn đề này.

2. Sử dụng DefiniteTyped

Một trong những điều đầu tiên bạn có thể làm là kiểm tra xem cộng đồng có cung cấp định nghĩa loại cho gói thông qua DefiniteTyped hay không. DefiniteTyped là một kho lưu trữ khổng lồ các định nghĩa kiểu được cộng đồng duy trì.


Đây là cách bạn kiểm tra và sử dụng các loại từ DefiniteTyped:


  1. Tìm kiếm định nghĩa loại cho gói của bạn bằng cách thử cài đặt chúng bằng npm. Các định nghĩa loại trên DefiniteTyped thường có tiền tố là @types/ .
 npm install @types/package-name


Ví dụ: nếu bạn đang sử dụng thư viện lodash , bạn sẽ chạy:

 npm install @types/lodash


  1. Sau khi cài đặt, bạn không cần nhập các loại này vào bất kỳ đâu trong dự án của mình một cách rõ ràng. TypeScript sẽ tự động phát hiện và sử dụng chúng, cho phép bạn nhập và sử dụng các thư viện như bình thường, đồng thời nhận được tính năng tự động hoàn thành và kiểm tra kiểu.


Nhưng điều gì sẽ xảy ra nếu không có định nghĩa kiểu nào trên DefiniteTyped?


3. Tạo hồ sơ khai báo của riêng bạn

Nếu DefiniteTyped không có định nghĩa kiểu bạn cần thì đã đến lúc tạo tệp khai báo tùy chỉnh. Mặc dù cách tiếp cận này đòi hỏi nhiều nỗ lực hơn nhưng nó đảm bảo dự án TypeScript của bạn hoạt động trơn tru với thư viện JavaScript.


Đây là phiên bản đơn giản hóa những gì bạn có thể làm:


  1. Tạo một tệp mới có phần mở rộng .d.ts trong thư mục nguồn (hoặc types ) của dự án của bạn. Đây có thể là một cái gì đó giống như declarations.d.ts


  2. Trong tệp này, bạn sẽ muốn khai báo mô-đun và có thể phác thảo cấu trúc cơ bản mà bạn mong đợi từ thư viện. Ví dụ:

 // This is a simplistic type declaration file for a hypothetical package. // We declare the module so TypeScript recognizes it. declare module 'name-of-untyped-package' { // Below, we're declaring a very basic structure. It's saying // there's a function we're expecting to exist, which returns any. // Ideally, you'd want to flesh this out with more specific types // if you know them or as you learn more about the library. export function functionName(arg: any): any; // You can continue to define the shapes of other functions or variables // you expect to exist within the package. The more detailed you are here, // the more helpful your type checking will be. }


Tệp khai báo tự chế này sẽ không đầy đủ như một tập hợp đầy đủ các định nghĩa kiểu, nhưng nó cho TypeScript biết: "Hãy tin tôi, tôi biết mô-đun này tồn tại và nó cung cấp các hàm/biến này." Từ đây, bạn có thể xây dựng các định nghĩa chi tiết hơn nếu cần.


Hãy nhớ rằng, việc xử lý các gói không phải TypeScript có thể gặp một chút trở ngại, nhưng những chiến lược này đảm bảo dự án TypeScript của bạn vẫn mạnh mẽ và có được sự an toàn về loại cũng như khả năng dự đoán mà chúng tôi đang theo đuổi. Đó là tất cả về sự tự tin vào cơ sở mã của bạn!



Thực tiễn tốt nhất và những cạm bẫy phổ biến

Chuyển sang TypeScript trong dự án React của bạn không chỉ là thay đổi phần mở rộng tệp và thêm chú thích loại. Đó cũng là việc điều chỉnh tư duy và phương pháp phát triển của bạn để tận dụng tối đa những gì TypeScript cung cấp đồng thời tránh những trở ngại thường gặp. Vì vậy, hãy thảo luận về một số phương pháp hay nhất và những cạm bẫy phổ biến mà bạn có thể gặp phải trong hành trình này.

1. Thực tiễn tốt nhất

1.1 Dựa vào suy luận kiểu

Mặc dù việc chú thích mọi thứ có thể rất hấp dẫn, nhưng một trong những điểm mạnh của TypeScript là khả năng suy luận kiểu của nó. Thường không cần thiết phải thêm các loại rõ ràng vào mỗi đoạn mã của bạn.

 // Instead of this: let x: number = 0; // You can rely on type inference: let x = 0; // TypeScript knows this is a number

Chú thích quá mức có thể làm cho mã của bạn dài dòng mà không thêm giá trị. Tin tưởng TypeScript để suy ra các loại nếu có thể.

1.2 Nắm Bắt Các Loại Tiện Ích

Các loại tiện ích cung cấp những cách linh hoạt để xử lý các loại trong các tình huống khác nhau. Chúng có thể giúp bạn tiết kiệm rất nhiều công sức và giúp việc xử lý kiểu của bạn hiệu quả hơn.

 // Example of using Partial to make all properties in an object optional function updateProfile(data: Partial<UserProfile>) { // function implementation } // Now you can pass only the parts of UserProfile you need to update updateProfile({ username: "newUserName" }); // This is valid

Partial , Readonly , Pick và các loại tiện ích khác có thể cực kỳ tiện dụng.

1.3 Sử dụng Enum cho các tập hằng số đã biết

Khi bạn có một thuộc tính chỉ có thể nhận các giá trị cụ thể, việc sử dụng enum có thể làm rõ ý định của bạn trong khi cung cấp xác thực cho các giá trị đó.

 enum UserRole { Admin = 'ADMIN', User = 'USER', Guest = 'GUEST', } // Now UserRole can only be one of the values defined in the enum function assignRole(role: UserRole) { // function implementation }

1.4 Ưu tiên giao diện cho định nghĩa cấu trúc đối tượng

Mặc dù typeinterface thường có thể được sử dụng thay thế cho nhau, nhưng việc sử dụng interface để xác định cấu trúc của đối tượng hoặc lớp sẽ giúp mã của bạn dễ đọc hơn và cung cấp thông báo lỗi tốt hơn.

 interface UserProfile { username: string; email: string; // More properties... }


2. Những cạm bẫy thường gặp

2.1 Lạm dụng any

Việc sử dụng any sẽ phủ nhận lợi ích của TypeScript bằng cách bỏ qua việc kiểm tra loại. Mặc dù có vẻ như đây là một cách khắc phục nhanh nhưng nó làm cho mã của bạn kém an toàn và khó dự đoán hơn.

 // Try to avoid this: let userData: any = fetchData(); // Instead, define a type for the data you expect: let userData: UserProfile = fetchData();

2.2 Bỏ qua cảnh báo của trình biên dịch

Cảnh báo trình biên dịch của TypeScript luôn sẵn sàng trợ giúp bạn. Việc bỏ qua những điều này có thể dẫn đến các loại lỗi và sự cố tương tự mà bạn đang cố tránh bằng cách sử dụng TypeScript.

2.3 Bị lạc trong các kiểu phức tạp

Đôi khi, trong nỗ lực tạo ra các loại chính xác, các nhà phát triển tạo ra các định nghĩa loại cực kỳ phức tạp, khó hiểu và khó duy trì. Nếu các kiểu của bạn ngày càng phức tạp, có lẽ đã đến lúc đơn giản hóa hoặc cấu trúc lại mã của bạn.

2.4 Quên các loại thư viện của bên thứ ba

Nếu bạn đang sử dụng thư viện của bên thứ ba, hãy luôn kiểm tra xem có loại TypeScript hiện có trên DefiniteTyped hay không. Không làm như vậy có thể đồng nghĩa với việc bỏ lỡ các tính năng an toàn loại cho các thư viện này.

Tóm lại, việc áp dụng TypeScript không chỉ đơn thuần là sử dụng một cú pháp mới; đó là việc áp dụng các phương pháp mới giúp tránh lỗi, làm cho mã dễ đọc hơn và cải thiện việc bảo trì. Tránh các bẫy thông thường và hãy nhớ rằng mục tiêu là viết mã sạch hơn, đáng tin cậy hơn và dễ bảo trì hơn!




Phần kết luận

Chà, mọi người, chúng ta đã đi đến cuối hành trình di chuyển TypeScript của mình. Đó là một chuyến đi khá dài phải không? Chúng tôi bắt đầu với câu hỏi lớn là "tại sao" và đi sâu vào vấn đề thực sự của việc chuyển một dự án React từ JavaScript sang TypeScript. Từ việc thiết lập môi trường TypeScript của bạn đến tái cấu trúc các thành phần, quản lý trạng thái, xử lý các tuyến và thậm chí xử lý các gói không phải TypeScript phiền phức đó, chúng tôi đã đề cập đến rất nhiều vấn đề.


Suy ngẫm về hành trình này, rõ ràng rằng việc di chuyển sang TypeScript không chỉ là 'tìm kiếm và thay thế' các tệp .js bằng .tsx . Đó là một bước đi chiến lược bao gồm việc học các quy ước mới, hiểu sâu các loại và quan trọng nhất là thay đổi cách chúng ta nghĩ về độ tin cậy và tính nhất quán của mã.


Dưới đây là một số điều rút ra khi chúng tôi kết thúc:

  1. Mạng lưới an toàn : TypeScript đã giới thiệu một lớp an toàn cho dự án của chúng tôi, phát hiện lỗi trước khi chúng tàn phá trong thời gian chạy. Mạng lưới an toàn này, khi bạn đã quen với nó, sẽ là yếu tố thay đổi cuộc chơi về độ tin cậy đối với mã của bạn và tốc độ phát triển tổng thể.


  2. Giao tiếp rõ ràng hơn : Với các loại, mã của chúng tôi hiện giao tiếp rõ ràng hơn. Cho dù bạn đang xem lại mã của mình hay một thành viên mới trong nhóm đang cố gắng hiểu cấu trúc thành phần của bạn, TypeScript sẽ đóng vai trò như một lớp tài liệu bổ sung.


  3. Tự tin tái cấu trúc : Bạn sợ tái cấu trúc? Chà, TypeScript luôn hỗ trợ bạn. Với các loại đảm bảo hợp đồng trong mã của bạn, nhiều lỗi tiềm ẩn sẽ được phát hiện trong các giai đoạn tái cấu trúc, giúp quá trình này bớt khó khăn hơn.


  4. Cộng đồng và Hệ sinh thái : Sử dụng TypeScript mở ra cánh cửa cho một hệ sinh thái thịnh vượng. Từ các thư viện đã nhập trên DefiniteTyped đến sự hỗ trợ vô tận trên các diễn đàn cộng đồng và tích hợp gói bên thứ ba hợp lý hơn, bạn đang ở trong một công ty tốt.


  5. Đường cong học tập : Có, TypeScript giới thiệu một đường cong học tập. Có lẽ đã có những khoảnh khắc thất vọng, nhầm lẫn về các loại và giao diện hoặc vật lộn với trình biên dịch. Tuy nhiên, hãy nhìn lại hành trình của bạn và bạn sẽ thấy hiện tại bạn hiểu mã của mình và hành vi của nó nhiều hơn đến mức nào.


Hãy nhớ rằng, quá trình chuyển đổi sang TypeScript không phải là một cuộc chạy nước rút; đó là một cuộc chạy marathon. Ban đầu có thể có một số trở ngại, nhưng những lợi ích lâu dài về chất lượng mã, khả năng dự đoán và khả năng bảo trì rất đáng nỗ lực.


Khi bạn tiếp tục hành trình phát triển của mình, hãy tiếp tục khám phá, học hỏi và chia sẻ kinh nghiệm của bạn với TypeScript. Mỗi thử thách là một cơ hội để học hỏi. Bản thân bạn trong tương lai (và nhóm của bạn) sẽ cảm ơn bạn vì cơ sở mã mạnh mẽ, an toàn về kiểu và dễ bảo trì hơn đáng kể mà bạn đang phát triển ngày nay.


Cảm ơn bạn đã cùng tôi khám phá TypeScript với React. Tiếp tục viết mã, tiếp tục cải thiện và quan trọng nhất là tận hưởng quá trình này!


Giữ liên lạc

Nếu bạn thích bài viết này và muốn khám phá thêm về phát triển web, vui lòng kết nối với tôi trên nhiều nền tảng khác nhau:

dev.to

hackernoon.com

hashnode.com

twitter.com


Phản hồi và câu hỏi của bạn luôn được chào đón.

Hãy tiếp tục học hỏi, viết mã và tạo ra các ứng dụng web tuyệt vời.


Chúc mừng mã hóa!



Tài nguyên bổ sung

Mặc dù hướng dẫn của chúng tôi đã kết thúc nhưng cuộc phiêu lưu của bạn với TypeScript vẫn chưa dừng ở đây. Thế giới của TypeScript rất rộng lớn, với vô số tài nguyên để khám phá, học hỏi và đóng góp. Dưới đây là một số tài nguyên có giá trị có thể giúp củng cố sự hiểu biết của bạn và giúp bạn luôn cập nhật trong cộng đồng TypeScript.


  1. Tài liệu chính thức của TypeScript : Không có nơi nào tốt hơn để khám phá TypeScript ngoài trang web chính thức của nó. Nó chứa đầy tài liệu, ví dụ và giải thích chi tiết về các tính năng khác nhau.


  2. DefiniteTyped : Khi làm việc với các thư viện của bên thứ ba, DefiniteTyped là một cứu cánh. Đó là một kho lưu trữ khổng lồ các định nghĩa kiểu TypeScript chất lượng cao.


  3. React TypeScript Cheatsheet : Bảng cheat toàn diện này phục vụ đặc biệt cho các nhà phát triển React đang chuyển sang TypeScript, bao gồm các mẫu và cách thực hành phổ biến.


  4. TypeScript Deep Dive : Một cuốn sách trực tuyến xuất sắc cung cấp thông tin khám phá chi tiết về TypeScript. Deep Dive giải thích sự thực tế của TypeScript bằng cách tập trung vào các tình huống thực tế.


  5. Kho lưu trữ TypeScript GitHub : Tương tác với cộng đồng và cập nhật những phát triển mới nhất trong TypeScript bằng cách truy cập kho lưu trữ TypeScript GitHub chính thức .


  6. Tràn ngăn xếp : Thẻ TypeScript trên Stack Overflow là trung tâm của các truy vấn phổ biến (và không phổ biến) cũng như các trường hợp sử dụng đa sắc thái mà các nhà phát triển trên toàn thế giới gặp phải. Đó là một mỏ vàng của những hiểu biết thực tế.


  7. TypeScript Weekly : Một bản tin được tuyển chọn, TypeScript Weekly cung cấp các bài viết, mẹo và tài nguyên mới nhất thẳng tới hộp thư đến của bạn.


  8. Kênh Reddit và Discord : Các cộng đồng trên các nền tảng như r/Typescript của Reddit và các kênh Discord khác nhau tổ chức các cuộc thảo luận, tin tức và chủ đề giải quyết vấn đề sôi nổi liên quan đến TypeScript.


  9. Blog TypeScript chính thức : Để biết các thông báo, tìm hiểu sâu và hướng dẫn từ nhóm TypeScript, hãy xem blog chính thức .


  10. Nền tảng mã hóa trực tuyến : Trải nghiệm học tập tương tác thông qua các nền tảng như Codecademy , freeCodeCampScrimba cung cấp các khóa học TypeScript thực hành.


Hãy nhớ rằng, cộng đồng phát triển nhờ sự tham gia. Đừng ngần ngại đặt câu hỏi, đóng góp câu trả lời hoặc chia sẻ giải pháp và kinh nghiệm của bạn. Trí tuệ tập thể của các diễn đàn cộng đồng, tài liệu chính thức và thực hành liên tục sẽ hướng dẫn bạn thành thạo TypeScript.


Chúc mừng mã hóa!