React 中的TypeScript開發范式

在 TypeScript 中使用 React 可以提高代碼的可維護性、可讀性和可靠性。TypeScript 提供了靜態類型檢查和豐富的類型系統,這些功能在 React 開發中非常有用。下面詳細介紹如何在 React 項目中使用 TypeScript,并結合泛型和 infer 來定義類型。

1.?項目初始化

首先,創建一個使用 TypeScript 的 React 項目:

pnpm create vite my-app --template react-ts
cd my-app

2.?基本用法

在 TypeScript 中,可以為組件的 props 和 state 定義類型。

函數組件:

import React from 'react';
interface GreetingProps {name: string;
}const Greeting: React.FC<GreetingProps> = (( name )) => {return <h1>Hello, {name}!</h1>;
};export default Greeting;

類組件:

import React, { Component } from 'react';interface CounterProps {initialCount?: number;
}interface CounterState {count: number;
}class Counter extends Component<CounterProps, CounterState> {static defaultProps = {initialCount: 0,};constructor(props: CounterProps) {super(props);this.state = { count: props.initialCount || 0 };render() {return (<div><p>Count: {this.state.count}</p><button onClick={() => this.setState({count: this.state.count + 1})}>Increment</button></div>);}}
}export default Counter;

3. 使用泛型

泛型允許我們定義可以在多種類型之間復用的組件和函數。

要想定義出靈活的組件類型,泛型和 infer 的使用必不可少,如果你在?React 開發過程中大量用到 any ,說明你你沒有真正掌握 Typescript,因為只要你靈活掌握了 Typescript,那么在項目中所有的類型均能通過類型定義來推導約束。

示例:泛型列表組件

import React from 'react';interface ListProps<T> {items: T[];renderItem: (item: T) => React.ReactNode;
}function List<T>({ items, renderItem }: ListProps<T>) {return (<ul>{items.map((item, index) => (<li key={index}>{renderItem(item)}</li>))}</ul>);
}// 使用泛型列表組件
const NumberList = () => {const numbers = [1, 2, 3, 4, 5];return <List items={numbers} renderItem={(num) => <span>{num}</span>} />;
};const StringList = () => {const strings = ['one', 'two', 'three'];return <List items={strings} renderItem={(str) => <strong>{str}</strong>} />;
};export { NumberList, StringList };

4.?使用 infer 定義類型

infer 關鍵字可以在條件類型中使用,用于推斷類型。

示例:推斷函數返回類型

type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;function getUser() {return { name: 'John', age: 30 };
}type User = GetReturnType<typeof getUser>; // { name: string; age: number; }

示例:推斷組件 props 類型

import React, { ComponentType } from 'react';type InferProps<T> = T extends ComponentType<infer P> ? P : never;const MyComponent = (props: { name: string; age: number }) => {return <div>{props.name} is {props.age} years old.</div>;
};type MyComponentProps = InferProps<typeof MyComponent>; // { name: string; age: number }

5. 綜合示例

綜合示例:使用 TypeScript、泛型和 infer 定義類型并在 React 組件中使用。

import React from 'react';// 定義一個數據類型
interface User {id: number;name: string;
}// 定義一個泛型函數組件,接收數據和渲染函數作為參數
interface DataListProps<T> {data: T[];renderItem: (item: T) => React.ReactNode;
}const DataList = <T,>({ data, renderItem }: DataListProps<T>) => {return (<ul>{data.map((item) => (<li key={(item as any).id}>{renderItem(item)}</li>))}</ul>);
};// 使用 infer 推斷組件 props 類型
type InferProps<T> = T extends React.ComponentType<infer P> ? P : never;// 創建一個渲染 user 數據的組件
const UserList: React.FC<DataListProps<User>> = (props) => {return <DataList {...props} />;
};// 使用 UserList 組件
const App: React.FC = () => {const users: User[] = [{ id: 1, name: 'John' },{ id: 2, name: 'Jane' },];return (<div><h1>User List</h1><UserList data={users} renderItem={(user) => <span>{user.name}</span>} /></div>);
};export default App;

在這個綜合示例中:

1. 定義了一個 User 類型;

2. 創建了一個泛型組件 Datalist,用于渲染任意類型的數據列表;

3. 使用 infer 推斷 UserList 組件的 props 類型;

4. 在 App 組件中使用 UserList 組件渲染用戶數據列表;

6.?針對 React 的進階版 tsconfig

tsconfig.json 是 TypeScript 項目配置的重要文件,通過合理配置,可以提高開發效率和代碼質量。

針對 React 項目,重點配置項包括目標版本、庫、模塊解析、JSX 支持以及嚴格類型檢查選項。

根據項目需求,可以進一步調整和擴展配置,確保最佳的開發體驗。

這是一個基礎的 tsconfig.json 示例,適用于大多數 React 項目:

{"compilerOptions": {"target": "es2017", // 指定 ECMAScript 目標版本。ES5 兼容性最好,可以在大多數瀏覽器中運行"lib": ["dom", "dom.iterable", "esnext"], // 指定編譯時包含的庫文件。通常包括 dom、dom.iterable和esnext"allowJs": true, // 允許編譯 .js 文件。適用于項目中混合使用 TypeScript 和 JavaScript 文件"skipLibCheck": true, // 跳過類型聲明文件的類型檢查。可以加快編譯速度"esModuleInterop": true, // 允許對 ES 模塊默認導入進行編譯時的兼容處理"allowSyntheticDefaultImports": true, // 允許從沒有默認導出的模塊中默認導入。與 esModuleInterop 配合使用"strict": true, // 啟用所有嚴格類型檢查選項。建議開啟以確保類型安全"forceConsistentCasingInFileNames": true, // 禁止文件名大小寫不一致。保證跨平臺一致性"module": "esnext", // 指定模塊代碼生成方式。esnext 適用于現代 JavaScript 運行環境"moduleResolution": "node", // 指定模塊解析策略。node 適用于 Node.js 生態系統"resolveJsonModule": true, // 允許導入 JSON 文件"isolatedModules": true, // 將每個文件作為獨立的模塊。對 Babel 等工具很有用"noEmit": true, // 禁止生成輸出文件。適用于僅進行類型檢查的項目"jsx": "react-jsx", // 指定 JSX 代碼生成方式。React 17 及以上版本推薦使用 react-jsx"baseUrl": "./src", // 配置基地址,使導入模塊時更簡潔"paths": { // 配置路徑別名,使導入模塊時更簡潔"@components/*": ["components/*"],"@utils/*": ["utils/*"]},"strictNullChecks": true, // 啟用嚴格的 null 檢查"noImplicitAny": true, // 禁止隱式的 any 類型"noImplicitThis": true, // 禁止隱式的 this 類型"alwaysStrict": true, // 如終以嚴格模式"noUnusedLocals": true, // 報告未使用的局部變量"noUnusedParameters": true, // 報告未使用的函數參數"noImplicitReturns": true, // 所有代碼路徑必須顯式返回值"noFallthroughCasesInSwitch": true // 禁止 switch 語句中的 case 語句貫穿},"include": ["src"], // 指定要包含的文件和目錄。通常指定src 目錄"exclude": ["node_modules", "build"] // 排除指定的目錄
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83196.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83196.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83196.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

72道Nginx高頻題整理(附答案背誦版)

1. 簡述什么是Nginx &#xff1f; Nginx 是一個開源的高性能HTTP和反向代理服務器&#xff0c;也能夠用作IMAP/POP3/SMTP代理服務器。它最初由Igor Sysoev為俄羅斯的一個大型網站Rambler開發&#xff0c;并在2004年首次公開發布。Nginx被設計用來解決C10k問題&#xff0c;即同…

AI時代,數據分析師如何成為不可替代的個體

在數據爆炸的 AI 時代&#xff0c;AI工具正以驚人的速度重塑數據分析行業&#xff0c;數據分析師的工作方式正在經歷一場前所未有的變革。數據分析師又該如何破局&#xff0c;讓自己不被AI取代呢&#xff1f; 一、AI工具對重復性工作的徹底解構 如以往我們需要花幾天寫一份數…

DockerHub與私有鏡像倉庫在容器化中的應用與管理

哈嘍&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的應用與管理 Docker Hub的基本概念與使用方法 Docker Hub是Docker官方提供的一個公共鏡像倉庫&#xff0c;用戶可以在其中找到各種操作系統、軟件和應用的鏡像。開發者可以通過Docker Hub輕松獲取所…

Kafka入門-Broker以及文件存儲機制

Kafka Broker Broker實際上就是kafka實例&#xff0c;每一個節點都是獨立的Kafka服務器。 Zookeeper中存儲的Kafka信息 節點的服役以及退役 服役 首先要重新建立一臺全新的服務器105&#xff0c;并且在服務器中安裝JDK、Zookeeper、以及Kafka。配置好基礎的信息之后&#x…

dexcap升級版之DexWild——面向戶外環境的靈巧手交互策略:人類和機器人演示協同訓練(人類直接帶上動捕手套采集數據)

前言 截止到25年6.6日&#xff0c;在沒動我司『七月在線』南京、武漢團隊的機器的前提下&#xff0c;長沙這邊所需的前幾個開發設備都已到齊——機械臂、宇樹g1 edu、VR、吊架 ?長沙團隊必須盡快追上南京步伐 加速前進 如上篇文章所說的&#xff0c; 為盡快 讓近期新招的新同…

【基于阿里云搭建數據倉庫(離線)】使用UDTF時出現報錯“FlatEventUDTF cannot be resolved”

目錄 問題&#xff1a; 可能的原因有&#xff1a; 解決方法&#xff1a; 問題&#xff1a; 已經將包含第三方依賴的jar包上傳到dataworks&#xff0c;并且成功注冊函數&#xff0c;但是還是報錯&#xff1a;“FlatEventUDTF cannot be resolved”&#xff0c;如下&#xff1a…

06 Deep learning神經網絡編程基礎 激活函數 --吳恩達

深度學習激活函數詳解 一、核心作用 引入非線性:使神經網絡可學習復雜模式控制輸出范圍:如Sigmoid將輸出限制在(0,1)梯度傳遞:影響反向傳播的穩定性二、常見類型及數學表達 Sigmoid σ ( x ) = 1 1 +

【LC實戰派】小智固件編譯

這篇寫給立創吳總&#xff0c;是節前答應他配合git代碼的說明&#xff1b;也給所有對小智感興趣的小伙伴。 請多提意見&#xff0c;讓這份文檔更有價值 - 第一當然是拉取源碼 - git clone https://github.com/78/xiaozhi-esp32.git 完成后&#xff0c;先查看固件中實際的…

有沒有 MariaDB 5.5.56 對應 MySQL CONNECTION_CONTROL 插件

有沒有 MariaDB 對應 MySQL CONNECTION_CONTROL 插件 背景 寫這篇文章的目的是因為昨晚半夜突然被call起來&#xff0c;有一套系統的mysql數據庫啟動失敗了。嘗試了重啟服務器也不行。讓我協助排查一下問題出在哪。 分析過程 一開始拿到服務器IP地址&#xff0c;就去數據庫…

初學 pytest 記錄

安裝 pip install pytest用例可以是函數也可以是類中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…

【LeetCode】算法詳解#6 ---除自身以外數組的乘積

1.題目介紹 給定一個整數數組 nums&#xff0c;返回 數組 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。 題目數據 保證 數組 nums之中任意元素的全部前綴元素和后綴的乘積都在 32 位 整數范圍內。 請 不要使用除法&#xff0c;且在 O…

Kubernetes 節點自動伸縮(Cluster Autoscaler)原理與實踐

在 Kubernetes 集群中&#xff0c;如何在保障應用高可用的同時有效地管理資源&#xff0c;一直是運維人員和開發者關注的重點。隨著微服務架構的普及&#xff0c;集群內各個服務的負載波動日趨明顯&#xff0c;傳統的手動擴縮容方式已無法滿足實時性和彈性需求。 Cluster Auto…

LLMs 系列科普文(11)

目前我們已經介紹了大語言模型訓練的兩個主要階段。第一階段被稱為預訓練階段&#xff0c;主要是基于互聯網文檔進行訓練。當你用互聯網文檔訓練一個語言模型時&#xff0c;得到的就是所謂的 base 模型&#xff0c;它本質上就是一個互聯網文檔模擬器&#xff0c;我們發現這是個…

深度學習環境配置指南:基于Anaconda與PyCharm的全流程操作

一、環境搭建前的準備 1. 查看基礎環境位置 conda env list 操作說明&#xff1a;通過該命令確認Anaconda默認環境&#xff08;base&#xff09;所在磁盤路徑&#xff08;如D盤&#xff09;&#xff0c;后續操作需跳轉至該磁盤根目錄。 二、創建與激活獨立虛擬環境 1. 創…

【2D與3D SLAM中的掃描匹配算法全面解析】

引言 掃描匹配(Scan Matching)是同步定位與地圖構建(SLAM)系統中的核心組件&#xff0c;它通過對齊連續的傳感器觀測數據來估計機器人的運動。本文將深入探討2D和3D SLAM中的各種掃描匹配算法&#xff0c;包括數學原理、實現細節以及實際應用中的性能對比&#xff0c;特別關注…

力扣160.相交鏈表

題目描述 難度&#xff1a;簡單 示例 思路 使用雙指針 使用指針分別指向兩個不同的鏈表進行比較 解題方法 1.首先進行非空判斷 2.初始化指針分別指向兩個鏈表 3.遍歷鏈表 while (pA ! pB)&#xff1a; 當pA和pB不相等時&#xff0c;繼續循環。如果pA和pB相等&#xff0c;說明找…

本地項目push到git

cd /home/user/project git init 添加遠程倉庫地址 git remote add origin https://github.com/user/repo.git 創建并切換到新分支 git checkout -b swift 添加文件到暫存區 git add . git commit -m “swift訓練評測” git push -u origin swift —force #首次 git push …

uni-app學習筆記二十九--數據緩存

uni.setStorageSync(KEY,DATA) 將 data 存儲在本地緩存中指定的 key 中&#xff0c;如果有多個key相同&#xff0c;下面的會覆蓋掉原上面的該 key 對應的內容&#xff0c;這是一個同步接口。數據可以是字符串&#xff0c;可以是數組。 <script setup>uni.setStorageSyn…

GitHub 趨勢日報 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系統生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日獲星趨勢圖 今日獲星趨勢圖 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…

NFC碰碰卡發視頻源碼搭建與寫卡功能開發實踐

在信息快速傳播的時代&#xff0c;便捷的數據交互方式成為用戶的迫切需求。“碰一碰發視頻” 結合寫卡功能&#xff0c;為視頻分享提供了新穎高效的解決方案&#xff0c;在社交娛樂、商業推廣等場景中展現出巨大潛力。本文將詳細介紹碰一碰發視頻源碼搭建以及寫卡功能開發的全過…