paint-brush
如何将 React 项目从 JavaScript 迁移到 TypeScript经过@leandronnz
15,604 讀數
15,604 讀數

如何将 React 项目从 JavaScript 迁移到 TypeScript

经过 Leandro Nuñez24m2023/10/19
Read on Terminal Reader

太長; 讀書

将 React 项目从 Javascript 迁移到 TypeScript 不仅仅是将 .js 文件“搜索并替换”为 .tsx。这是一项战略举措,涉及学习新约定、深入理解类型,最重要的是,改变我们对代码可靠性和一致性的看法。 以下是一些注意事项: 安全网:TypeScript 为我们的项目引入了一个安全层,可以在错误在运行时造成严重破坏之前捕获它们。一旦您习惯了这个安全网,就会改变游戏规则,提高您对代码的信心和整体开发速度。 更清晰的沟通:通过类型,我们的代码现在可以更明确地进行沟通。无论是您重新访问代码还是新团队成员尝试了解组件结构,TypeScript 都可以充当附加文档层。 重构信心:害怕重构?好吧,TypeScript 为您提供支持。通过确保代码中的契约的类型,可以在重构阶段捕获许多潜在的错误,从而使该过程不再那么令人畏惧。 社区和生态系统:拥抱 TypeScript 为繁荣的生态系统打开了大门。从DefinitelyTyped 上的类型化库到社区论坛上的无尽支持以及更简化的第三方包集成,您处于良好的伙伴关系中。 学习曲线:是的,TypeScript 引入了学习曲线。可能会有一些沮丧的时刻,对类型和接口的困惑,或者与编译器的斗争。但是,回顾一下您的旅程,您会发现您现在对代码及其行为有了更多的了解。
featured image - 如何将 React 项目从 JavaScript 迁移到 TypeScript
Leandro Nuñez HackerNoon profile picture
0-item


目录

  • 介绍

  • 为什么要迁移?了解好处

  • 开始之前:先决条件

  • 启动迁移:在项目中设置 TypeScript

  • 重构 React 组件

  • 状态管理和上下文 API

  • 路由和异步操作

  • 在 TypeScript 中测试

  • 处理非 TypeScript 包

  • 最佳实践和常见陷阱

  • 结论

  • 其他资源



介绍

嘿,开发人员朋友们!很高兴在这里见到您,准备在我们的 React 项目中探索从JavaScriptTypeScript的过渡。


现在,如果您使用过 JavaScript,您就会知道它就像那双旧的、舒适的鞋子 - 有点磨损,有时难以预测,但很熟悉。然而,TypeScript 就像用定制鞋垫升级鞋子一样;这是相同的步行体验,但有额外的支撑。


那么,关于 TypeScript 有哪些热门话题呢?


嗯,它本质上是 JavaScript,但添加了大量额外功能,其中最重要的是类型检查。


想象一下,没有那些令人讨厌的undefined is not a function错误。这就是 TypeScript 给你的生活带来的平静。


在本指南中,我们将逐步介绍将 TypeScript 集成到 React 项目中的原因和方法。


为什么要反应?因为它太棒了,而且我们显然喜欢它。而且,将 React 基于组件的方法与 TypeScript 的类型检查功能相结合,可以带来非常高效和愉快的编码体验。


以下是向项目添加 TypeScript 的外观。在典型的 JavaScript 组件中,您将具有:

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


通过 TypeScript,我们引入了一种确保name始终被视为字符串的方法:

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


注意到type Props部分了吗?


这就是 TypeScript 的表达方式:“嘿,我在看;最好确保name是一个字符串!”这是一个简单的改变,却有着深远的影响。现在,您有一个守护天使主动防止与类型相关的错误,使您的代码更加健壮和可预测。


但这只是一小部分。我们将在这份综合指南中详细介绍 TypeScript 的诸多好处和实践。从设置环境到重构组件和道具,甚至是避免常见陷阱的最佳实践,我们有很多内容要介绍。所以,系好安全带,让我们开始这场演出吧!




为什么要迁移?了解好处

如果您正在考虑从 JavaScript 转向 TypeScript,尤其是在React项目中,那么您并不是唯一一个想知道“这真的值得这么麻烦吗?”的人。转换整个项目的语言并不是一件小事;它需要努力、学习,并且最初需要稍微放慢生产力。那么,开发人员为什么要做出这种转变呢?让我们来分析一下令人信服的理由。


1. 更快地捕获错误:静态类型检查

TypeScript 的核心特性是它的静态类型系统。与动态类型的 JavaScript 不同,TypeScript 允许您指定变量、函数参数和返回值的类型。有什么福利?早在代码接近生产之前,错误就在开发过程中被捕获。


考虑一个简单的例子:

 // 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!


现在,让我们看看 TypeScript 如何提供帮助:

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


使用 TypeScript,这个看似无辜的错误会被立即捕获,确保您在事故发生时就意识到它。这样,反馈循环就会缩短,您就不会为生产环境中的奇怪错误而摸不着头脑。


2. 提高代码质量和可理解性

TypeScript 对类型的强制执行意味着任何其他开发人员(甚至未来的您)都可以一目了然地了解函数需要什么类型的数据以及它返回什么。这种清晰度使代码库更具可读性和自记录性。


想象一下,遇到一个同事编写的 JavaScript 函数:

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


您可能需要深入研究该函数或找到它的使用位置来了解items应该是什么。有了 TypeScript,一切就很清楚了:

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


3. 增强的编辑器支持

TypeScript 通过改进的自动完成、重构和调试来增强文本编辑器和 IDE,将开发人员体验提升到一个新的水平。这种集成是可能的,因为 TypeScript 可以与您的编辑器共享其对代码的理解。

当您发现编辑器建议方法名称、提供函数参数信息或警告您函数使用不正确时,您就会遇到这种情况。这就像有一个副驾驶可以帮助浏览代码并提供额外的安全层。


4. 更轻松的协作

在团队环境中,TypeScript 通过帮助在整个代码库中实施某些标准和结构而大放异彩。当多个开发人员为一个项目做出贡献时,TypeScript 的严格规则可确保每个人都遵守相同的编码准则,从而使协作更加顺畅。这是一种通用语言,全面体现“质量和一致性”。


5. 让您的代码面向未来

JavaScript 正在不断发展,而 TypeScript 的目标是跟上最新功能。通过使用 TypeScript,您可以在下一代 JavaScript 功能成为主流之前就开始利用它们,确保您的项目保持现代和前沿。


总之,迁移到 TypeScript 不仅仅是为了更早地捕获错误;还为了更早地发现错误。这是关于编码过程的整体改进。从更好的团队协作到面向未来的项目,TypeScript 为构建可靠、可扩展和可维护的应用程序提供了坚实的基础。


做出这种转变一开始可能看起来令人畏惧,但有了上面列出的好处,很明显为什么 TypeScript 已成为全球许多开发人员的最爱。准备好潜入了吗?让我们继续吧!



开始之前:先决条件

好的,那么您已经准备好在 React 项目中切换到 TypeScript 了吗?伟大的决定!


但在我们深入实际流程之前,我们需要确保一些事情已经到位。

将此视为我们的准备阶段,我们准备好所有工具,以便过渡过程像黄油一样顺利。


以下是您需要准备的内容:

1.现有React项目

首先,您需要一个现有的 React 项目。这个项目应该是一个你可以轻松尝试的项目;虽然迁移过程非常简单,但您需要在一个可以暂时造成混乱的空间中进行此操作。


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


这个组件是一个很好的起点——它功能齐全、干净,而且我们一眼就能看出发生了什么。

2. TypeScript 的基本理解

您不需要成为 TypeScript 专家,但了解基础知识将使这种转变变得更加容易。


知道如何定义类型、接口,并知道typeinterface之间的区别。

一点家庭作业会有很大帮助,相信我。


 // 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;


看到不同?我们现在明确了Greeting期望,使我们的组件更可预测且更易于使用。


3. 节点和NPM/Yarn

您的开发环境应该安装 Node.js,因为我们将使用npmyarn来处理我们的包。由于您正在使用 React,所以这个要求是给定的,但确定一下也没有什么坏处,对吗?


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


您的终端应该向您显示这些工具的当前版本,确认它们已全部设置完毕并准备就绪。


4. 代码编辑器

您将需要一个可以很好地处理 TypeScript 的代码编辑器。 Visual Studio Code 深受大众喜爱,因为它内置了强大的 TypeScript 支持,通过智能代码完成和错误突出显示使开发过程更加顺畅。


5.版本控制

这一步不是强制性的,但却是明智的一步。确保您当前的项目处于 git 的版本控制之下。如果出现任何问题(尽管我们会尽力确保不会出现问题),您可以随时恢复到以前的版本,而不会失眠。


 # 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"


拥有这个安全网意味着您可以充满信心地进行实验,因为您知道您的背部已得到保护。


这就是我们的先决条件!您已经完成了该项目,温习了一些 TypeScript,您的环境已准备就绪,您的安全网也已就位。


现在,我们已准备好深入了解迁移过程。让我们开始吧!



启动迁移:在项目中设置 TypeScript 重构 React 组件

好啦,进入下一阶段!


我们已经用 TypeScript 做好了准备,但现在我们必须亲自动手。


是时候重构我们的 React 组件了。此步骤涉及的不仅仅是更改文件扩展名;我们需要更新组件代码以利用 TypeScript 的功能来获得更强大、无错误的编码体验。

让我们深入了解吧!


1. 更改文件扩展名

首先,让我们重命名我们的组件文件。此过程涉及将包含 JSX 代码的文件的扩展名从.js更改为.tsx


以下是如何从命令行在项目的源目录中集体执行此操作:

 # 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' }


这些命令搜索项目源目录中的所有.js文件并将它们重命名为.tsx 。这就像告诉你的文件,“欢迎来到 TypeScript 世界!”


2. 键入您的组件

重命名文件后,我们来处理代码。我们将从 JavaScript 中的一个简单的函数组件开始:

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


现在,让我们重构它以使用 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>; }


我们在这里做了什么?


我们定义了一个接口MyComponentProps来描述组件的 props,确保类型安全。通过说greeting是一个字符串,如果我们试图传递一个数字,TypeScript就会对我们大喊大叫。我们还使用了 React 类型定义中的FC类型( Functional Component的缩写),确保 TypeScript 知道它是一个 React 组件。


3. 强类型 useState 和 useEffect

让我们通过向状态和效果添加类型(功能组件的共同特征)来进一步升级我们的组件。


这是一个具有状态和效果的组件:

 // 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> ); }


让我们在这上面施展一些 TypeScript 魔法:

 // 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> ); }


在我们重构的组件中,我们明确告诉 TypeScript 期望count状态有一个number


这个细节可以防止出现令人讨厌的错误,在这些错误中,我们可能会意外地得到一个字符串、对象,或者天堂不允许, null而不是我们预期的数字。


我们开始吧!


我们已经成功重构了 React 组件以使用 TypeScript。通过显式输入我们的组件、状态和属性,我们正在创建一个更可预测且易于维护的代码库。我们不仅仅是编码;我们正在以应有的精度打造一件杰作。


接下来,我们将更深入地研究更复杂的场景以及 TypeScript 如何来帮助我们!



状态管理和上下文 API

现在,让我们深入了解 React 和 TypeScript 中状态管理的本质。如果您在 JavaScript 项目中使用过 Context API,您就会知道它是一个强大的功能,可以通过组件树传递数据,而无需在每个级别手动传递 props。在 TypeScript 中,我们获得了严格类型的额外好处,这使得我们的上下文数据更加健壮和可预测。


准备好加入了吗?我们走吧!


1. 创建类型化上下文

首先,我们将使用 TypeScript 创建一个新的上下文。此上下文将确保任何默认值、提供者值或消费者组件与我们预期的类型相匹配。


以下是在 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> ); };


现在,让我们使用 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> ); };


我们在这里所做的是创建一个 TypeScript 接口DataContextState ,它严格类型化我们的上下文数据。我们还输入了createContext函数和DataProvider组件,确保从状态变量到上下文值的所有内容都与我们定义的类型一致。


2. 使用类型化上下文

现在我们有了类型化的DataContext ,让我们看看如何在组件中使用它。


我们需要使用useContext钩子,具体方法如下:

 // 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> ); };


ComponentUsingContext中,我们正在访问上下文并期望 TypeScript 验证该值是否与DataContextState一致。我们的handleUpdateData函数演示了如何更新共享状态——调用setData时,任何使用DataContext的组件都会使用新数据重新呈现。


通过将 TypeScript 与 Context API 结合使用,我们确信共享状态管理在整个应用程序中是一致的。编译器会捕获上下文提供的内容与组件期望的内容之间的任何差异。这种协同作用使我们的代码更加可靠,开发过程更加顺畅,使我们能够避免可能遇到的所有类别的错误。


继续努力,记住,现在输入一点内容可以节省以后的大量调试!



TypeScript 中的路由和异步操作测试 >

现在我们已经了解了 TypeScript 如何改进 React 应用程序的各个方面,现在是时候讨论另一个关键领域:测试。


测试是确保我们的应用按预期工作的基础,而 TypeScript 可以使我们的测试更加可靠和高效。让我们深入研究一下 TypeScript 如何在测试中发挥作用,特别是在 React 项目中。


1. 为测试做好准备

在我们进入代码之前,请确保您已经安装了在 React 项目中进行测试所需的库。以下是 Jest 和 React 测试库的快速设置,广泛一起用于测试 React 应用程序:

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


这些库为编写单元和集成测试提供了强大的环境。现在,为了清楚起见,让我们考虑一个现实场景。


2. 真实测试场景:用户问候组件

想象一下,我们的应用程序中有一个简单的组件,可以根据一天中的时间向用户致意。它是一个功能组件,将用户名作为 props,将当前时间作为 state。


我们的UserGreeting组件可能如下所示:

 // 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;


现在,我们需要编写测试以确保我们的组件在不同条件下按预期运行。我们的测试用例将确认根据一天中的时间显示适当的问候语。


以下是我们如何使用 Jest 和 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. });


在此脚本中,我们在设定的时间(模拟为下午 2:00)渲染组件,并检查它是否按预期输出“下午好”。我们可以为一天中的其他时间(早上、晚上)编写更多测试,以确保我们的组件被完全覆盖。


通过 TypeScript,我们确保在测试中传递给组件的 props 与预期的类型匹配。这样,我们就可以避免遇到可能导致测试出现误报的错误 props 问题,从而确保我们的测试稳健可靠。


在测试中使用 TypeScript 有助于在开发过程的早期发现问题,使我们的应用程序更加健壮和可维护。这是一个双赢的局面!请记住,一致且全面的测试是高质量软件开发的标志。继续努力吧!




处理非 TypeScript 包

好吧,让我们解决一个在 React 项目中转向 TypeScript 时经常困扰人们的问题:处理不是用 TypeScript 编写的 JavaScript 库和包。这是一个常见的场景;你已经启动并运行了 TypeScript 项目,然后安装了第三方包,却发现 TypeScript 编译器出现了问题。不用担心;有解决方案。


1. 遇到问题

这是一个典型的场景:您尝试使用一个不支持 TypeScript 的包,TypeScript 编译器开始抛出错误,例如“找不到模块‘模块名称’的声明文件”。听起来有点熟?


出现此问题的原因是 TypeScript 依赖类型定义来理解库和包的结构。如果缺少这些类型定义,TypeScript 就会有点丢失。但不用担心,我们有策略来处理这个问题。

2. 使用DefinitelyTyped

您可以做的第一件事就是检查社区是否通过DefinitelyTyped 提供了包的类型定义。 DefinelyTyped 是由社区维护的大型类型定义存储库。


以下是检查和使用 DefinelyTyped 中的类型的方法:


  1. 通过尝试使用 npm 安装包来搜索包的类型定义。 DefinetlyTyped 上的类型定义通常以@types/为前缀。
 npm install @types/package-name


例如,如果您使用lodash库,您将运行:

 npm install @types/lodash


  1. 安装后,您不需要在项目中的任何位置显式导入类型。 TypeScript 将自动检测和使用它们,允许您照常导入和使用库,并获得自动完成和类型检查。


但是,如果 DefinelyTyped 上没有可用的类型定义怎么办?


3. 制作您自己的声明文件

如果DefinitelyTyped没有您需要的类型定义,那么就需要创建一个自定义声明文件。虽然这种方法需要更多的努力,但它可以确保您的 TypeScript 项目与 JavaScript 库顺利配合。


这是您可以执行的操作的简化版本:


  1. 在项目的源(或types )目录中创建一个扩展名为.d.ts新文件。这可能类似于declarations.d.ts


  2. 在此文件中,您需要声明模块并可能概述您期望从库中获得的基本结构。例如:

 // 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. }


这个自制的声明文件不会像全套类型定义那样全面,但它告诉 TypeScript,“相信我,我知道这个模块存在,并且它提供了这些函数/变量。”从这里,您可以根据需要构建更详细的定义。


请记住,处理非 TypeScript 包可能会有点困难,但这些策略可确保您的 TypeScript 项目保持健壮,并享受我们所追求的类型安全性和可预测性。这一切都与您对代码库的信心有关!



最佳实践和常见陷阱

在 React 项目中切换到 TypeScript 不仅仅是更改文件扩展名和添加类型注释。它还涉及调整您的思维方式和开发实践,以充分利用 TypeScript 提供的功能,同时避免常见的障碍。因此,让我们讨论一下您在此过程中可能遇到的一些最佳实践和常见陷阱。

1. 最佳实践

1.1 依靠类型推断

虽然注释所有内容可能很诱人,但 TypeScript 的优势之一是它的类型推断。通常没有必要向每段代码添加显式类型。

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

过度注释会使您的代码变得冗长而不会增加价值。信任 TypeScript 能够尽可能推断类型。

1.2 拥抱实用程序类型

实用程序类型提供了灵活的方式来处理各种场景中的类型。它们可以为您节省大量精力,并使您的类型处理更加高效。

 // 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

PartialReadonlyPick和其他实用程序类型非常方便。

1.3 使用枚举来表示已知的常量集

当您的属性只能采用特定值时,使用enum可以使您的意图清晰,同时对这些值进行验证。

 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 对象结构定义的首选接口

虽然typeinterface通常可以互换使用,但使用interface来定义对象或类的结构可以使代码更具可读性并提供更好的错误消息。

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


2. 常见陷阱

2.1 过度使用any

使用any会绕过类型检查,从而抵消了 TypeScript 的优势。虽然这看起来像是一个快速修复,但它使您的代码不太安全和可预测。

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

2.2 忽略编译器警告

TypeScript 的编译器警告可以为您提供帮助。忽略这些可能会导致您使用 TypeScript 试图避免的相同类型的错误和问题。

2.3 迷失在复杂类型中

有时,为了使类型变得精确,开发人员会创建极其复杂的类型定义,这些定义很难理解和维护。如果您的类型变得复杂,可能是时候简化或重构您的代码了。

2.4 忘记第三方库类型

如果您使用第三方库,请务必检查DefinitelyTyped 上是否存在现有的 TypeScript 类型。不这样做可能意味着错过这些库的类型安全功能。

总而言之,采用 TypeScript 不仅仅是使用新语法;还包括使用 TypeScript。它涉及采用新的实践来帮助避免错误、使代码更具可读性并改进维护。避免常见的陷阱,并记住,目标是编写更干净、更可靠、更可维护的代码!




结论

好了,各位,我们的 TypeScript 迁移之旅已经结束了。这真是一段旅程,不是吗?我们从“为什么”这个大问题开始,深入研究了将 React 项目从 JavaScript 转移到 TypeScript 的实质内容。从设置 TypeScript 环境到重构组件、管理状态、处理路由,甚至处理那些讨厌的非 TypeScript 包,我们已经涵盖了很多内容。


回顾这一历程,很明显,迁移到 TypeScript 不仅仅是将.js文件“搜索并替换”为.tsx 。这是一项战略举措,涉及学习新约定、深入理解类型,最重要的是,改变我们对代码可靠性和一致性的看法。


总结时,我们有以下几点要点:

  1. 安全网:TypeScript 为我们的项目引入了一个安全层,可以在错误在运行时造成严重破坏之前捕获它们。一旦您习惯了这个安全网,就会改变游戏规则,提高您对代码的信心和整体开发速度。


  2. 更清晰的沟通:通过类型,我们的代码现在可以更明确地进行沟通。无论是您重新访问代码还是新团队成员尝试了解组件结构,TypeScript 都可以充当附加文档层。


  3. 重构信心:害怕重构?好吧,TypeScript 为您提供支持。通过确保代码中的契约的类型,可以在重构阶段捕获许多潜在的错误,从而使该过程不再那么令人畏惧。


  4. 社区和生态系统:拥抱 TypeScript 为繁荣的生态系统打开了大门。从DefinitelyTyped 上的类型化库到社区论坛上的无尽支持以及更简化的第三方包集成,您处于良好的伙伴关系中。


  5. 学习曲线:是的,TypeScript 引入了学习曲线。可能会有一些沮丧的时刻,对类型和接口的困惑,或者与编译器的斗争。但是,回顾一下您的旅程,您会发现您现在对代码及其行为有了更多的了解。


请记住,向 TypeScript 的过渡并不是冲刺,而是一次冲刺。这是一场马拉松。最初可能会遇到一些障碍,但从长远来看,代码质量、可预测性和可维护性方面的收益是值得付出努力的。


当您继续您的开发之旅时,请不断探索、学习并分享您使用 TypeScript 的经验。每一次挑战都是一次学习的机会。未来的你(和你的团队)将感谢你今天所培养的健壮、类型安全且更易于维护的代码库。


感谢您与我一起探索 TypeScript 和 React。不断编码,不断改进,最重要的是,享受这个过程!


保持联系

如果您喜欢这篇文章并且想要探索有关 Web 开发的更多信息,请随时在各种平台上与我联系:

开发者

hackernoon.com

hashnode.com

推特.com


随时欢迎您的反馈和问题。

继续学习、编码并创建令人惊叹的 Web 应用程序。


快乐编码!



其他资源

尽管我们的指南已经结束,但您的 TypeScript 冒险之旅并没有就此结束。 TypeScript 的世界非常广阔,有大量的资源可供探索、学习和贡献。以下是一些有价值的资源,可以帮助您加深理解并让您随时了解 TypeScript 社区的最新动态。


  1. TypeScript 官方文档:没有比其官方网站更好的地方来探索 TypeScript 了。它包含详细的文档、示例和各种功能的解释。


  2. DefinelyTyped :在使用第三方库时, DefiniteTyped是一个救星。它是一个巨大的高质量 TypeScript 类型定义存储库。


  3. React TypeScript Cheatsheet :这个全面的备忘单专门针对过渡到 TypeScript 的 React 开发人员,涵盖了常见的模式和实践。


  4. TypeScript Deep Dive :一本优秀的在线书籍,提供了 TypeScript 的详细探索。 Deep Dive解释了 TypeScript 的本质,重点关注实际场景。


  5. TypeScript GitHub 存储库:通过访问官方 TypeScript GitHub 存储库与社区互动并了解 TypeScript 的最新发展。


  6. Stack Overflow :Stack Overflow上的 TypeScript 标签是全球开发人员遇到的常见(和不常见)查询和细微用例的中心。这是实践见解的金矿。


  7. TypeScript WeeklyTypeScript Weekly是一份精心策划的新闻通讯,将最新的文章、技巧和资源直接发送到您的收件箱。


  8. Reddit 和 Discord 频道Reddit 的 r/typescript等平台上的社区和各种 Discord 频道举办与 TypeScript 相关的活跃讨论、新闻和问题解决线程。


  9. 官方 TypeScript 博客:有关 TypeScript 团队的公告、深入研究和教程,请查看官方博客


  10. 在线编码平台:通过CodecademyfreeCodeCampScrimba等平台提供互动学习体验,提供实践 TypeScript 课程。


请记住,社区因参与而繁荣。请随时提出问题、贡献答案或分享您的解决方案和经验。社区论坛、官方文档和持续实践的集体智慧将引导您掌握 TypeScript。


快乐编码!