
React TypeScript教程
简介
TypeScript已经发展成为网络开发中最流行和最广泛使用的编程语言之一。TypeScript是JavaScript的一个超集。这意味着TypeScript本质上是带有一些额外功能的JavaScript。TypeScript的目标是编写强类型的JavaScript。强类型有助于以最小的错误来扩展网络应用。TypeScript代码通过使用TypeScript Compiler或Babel等编译器转换为JavaScript。
为了更好地理解,我们将使用React和TypeScript开发一个学生应用程序。本教程将为你提供在下一个项目中开始使用TypeScript所需的一切。
如果你想在YouTube上学习这个教程,可以通过下面的链接获得。
最终的解决方案可以在GitHub上找到。
GitHub - tndungu/React-TypeScript-StudentApp:React TypeScript学生应用程序
前提条件
本教程假定你有一些React的基本知识。
为什么使用TypeScript?
使用TypeScript有很多好处。主要的有以下几点。
- 强类型化确保在开发过程中捕获错误,而不是在应用程序处于生产状态时捕获错误。同时也使代码的调试变得容易。
- 文档--它可以作为JavaScript代码的文档,使其易于阅读和维护。
- 节省了开发时间。
- TypeScript中的泛型提供了一个强大的类型系统,给了开发者很大的灵活性。
TypeScript中的学生应用程序
我们将使用React建立一个应用程序,它将涵盖TypeScript的以下方面。
- Props
- 类型推理与类型注解
- 联盟类型
- 组织接口
- 枚举
- 泛型
应用开发。一步一步的指南
要启动一个新的typescript应用程序,请使用以下命令
- yarn:
yarn create-react-app student-app --template typescript
- npm:
npx create-react-app student-app --template typescript
cd进入student-app,然后yarn start或者npm start(如果使用npm)。
道具
我们将首先向组件传递一个道具。它将是一个字符串,包含应用程序的名称。这里我们将看到TypeScript的第一个用例。
修改App.tsx和index.tsx文件,如下所示。删除App.test.tsx文件。
//Index.tsx
const root = ReactDOM.createRoot(
//App.tsx
function App({ name }: AppName) {
export default App;
在你的浏览器上,你应该能够看到学生应用程序的显示。我们可以看到,AppName是一个接口,它有一个叫做name的属性。
一个接口是一个抽象的类型,编译器用它来知道一个给定的对象可以有哪些属性名称。它被用于类型检查。
在AppName接口中,属性名是一个字符串,这就是为什么我们要传递一个字符串给App组件。如果你试图传递任何其他类型,如整数或布尔值,应用程序将给出一个错误。它甚至不会被编译。如果你没有使用TypeScript,应用程序将被编译,但在部署后会出现意外的结果。
类型推理与类型注解
const [studentId,setStudentId] = useState(0)
setStudentId('test')
如果你尝试上面的代码,它将不会被编译,typecript会给出一个错误。这是因为typescript已经推断出studentId的类型是一个整数(数字)。如果你试图给studentId分配一个字符串,将在编译时产生一个错误。这在TypeScript中被称为类型推断。
同样,下面的代码也不会在TypeScript中运行。
const [student, setStudent] = useState(null)
setStudent({
这是因为TypeScript推断学生对象是null类型的,因此我们必须明确定义学生对象,并且在useState()钩子中我们必须告诉TypeScript用户可以是null或者学生对象。这被称为类型注解。我们将使用Student接口来做到这一点。我们的App.tsx的最终代码将如下所示。
import { useState } from "react";
export interface AppName {
export interface Student {
function App({ name }: AppName) {
const addStudent = () => {
return (
从上面的代码中,学生既可以是null也可以是Student对象。这被代码useState<Student | null>(null)所表示。这引入了另一个概念,叫做联合类型。
联合类型
当你有一个可以拥有不同类型的对象时。例如,你可能有 const [student, setStudent] = useState<Student | null | boolean>(null) 。在这种情况下,Student | null | boolean是联盟类型。
组织接口
就我们的接口而言,有两个问题。
- 我们不应该像在学生接口中那样嵌套对象。相反,我们应该为地址建立另一个接口。
- 为了便于维护和重复使用,这些接口应该在各自的模块中。
我们将为地址创建一个新的接口。然后我们将创建一个新的接口模块,在src文件夹中创建一个interface.ts文件,并将接口移到那里。然后我们将在App.tsx文件中导入我们的接口。最终的App.tsx和Interfaces.ts文件将看起来如下。
//App.tsx
function App({ name }: AppName) {
const addStudent = () => {
return (
export default App;
//interfaces.tsx
export interface Address {
export interface Student {
枚举
Enum是一种用于保存常量值的类型。在我们的例子中,学生级别可以是 "本科 "或 "研究生"。
export enum Level {
上述枚举可以用来根据学生的级别有条件地显示学生的年龄,如下所示。
{
泛型
泛型是TypeScript的一个重要特征,用于创建可重用的组件。如下图所示,同一个组件可以用来处理不同的数据类型。
使用同一个组件显示学生和课程列表。

对于我们的学生应用程序,我想显示2个列表。一个是学生的列表,另一个是课程的列表。如果没有泛型,我最终将创建2个组件,用来显示这两个列表。然而,有了泛型,我将只用一个组件来显示这两个列表。即使我们的应用程序越来越大,DisplayData组件也可以重复使用,以显示任何项目的列表。
在src文件夹中,我已经创建了DisplayData.tsx组件。该文件看起来如下。
interface Item {
interface DisplayDataItem<T> {
export const DisplayData = <T extends Item>({ items }: DisplayDataItem<T>) => {
接口Item有一个属性id,这意味着任何使用这个组件的对象必须有一个id属性。Interface DisplayDataItem是一个表示T类型的Array的对象,这意味着它可以被任何由项目数组组成的对象使用。DisplayData是一个接受项目数组并显示列表的函数。
下面是App.tsx、App.css和data.ts文件的最终代码。
//App.tsx
function App({ name }: AppName) {
const addStudent = () => {
return (
export default App;
//data.ts
export const coursesList = [
.App {
li{
button {
通用搜索功能
最后,我们将添加一个通用搜索,在这里,学生列表可以根据学生姓名或年龄点击按钮进行排序。
创建一个GenericSort.ts文件,确保你有以下代码。这段代码需要一个数组项目的列表和用于排序的键,然后返回排序后的列表。例如,如果我想根据学生姓名对学生列表进行排序,我将调用函数GenericSort(studentList, "name")
这是一个强大的泛型使用案例,如果我想根据不同的排序列对学生记录列表进行排序,我可以使用它。在没有TypeScript的情况下实现这一点,最终会出现许多难以扩展的函数。
//GenericSort
items.sort((a, b) => {
//App.tsx
function App({ name }: AppName) {
const addStudent = () => {
setStudent({
const sortData = () => {
GenericSort(studentList, "age")
export default App;
结论
太棒了!在这一点上,你已经经历了使用TypeScript构建React应用程序的核心构建模块。在我们项目的最后一部分,我们介绍了TypeScript的一些高级功能,泛型。
祝你使用TypeScript编码愉快。
如果你需要进一步的帮助,请随时在下面评论。
TypeScript与React教程最初发表在Dev Genius的Medium上,在那里人们通过强调和回应这个故事来继续对话。