這篇文章主要介紹了關於react專案靜態類型檢查方案,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
為什麼需要引入類型檢查
JS作為一個弱類型語言,具有很大的靈活性,但是它的優點也是它的缺點,它很容易讓我們忽略一些隱晦的邏輯,語法錯誤或資料類型錯誤,在編譯期甚至運行時看起來都不會報錯,但可能會發生各種奇怪的和難以解決的bug。
如
function getPrice(x) { return x * 10; } getPrice('a23') // NaN
function getDefaultValue (key, emphasis) { let ret; if (key === 'name') { ret = 'GuangWong'; } else if(key=== 'gender') { ret = 'Man'; }else if(key ==='age'){ ret = 18; } else { throw new Error('Unkown key '); } if (emphasis) { ret = ret.toUpperCase(); } return ret; } getDefaultValue('name'); // GuangWong getDefaultValue('gender', true) // MAN getDefaultValue('age', true)
這是一個簡單的函數,第一個參數 key 用來得到一個預設值。第二參數 emphasis 為了某些場景下要大寫強調,只需要傳入 true 即可自動將結果轉成大寫。
但如果不小心將 age 的值寫成了數字字面量,如果我呼叫 getDefaultValue('age', true) 就會在執行時報錯。這個有可能是業務上線了之後才發生,直接導致業務不可用
除此以外,在工作中,我們也經常遇到過對像上的一個屬性在n個模組之間傳遞之後變成了undefined。以上是程式碼健壯性的問題,工作中比較頭痛的另一個問題是協作性問題:如何讓一個別人提供的方法產出一個一目了然的文檔?因為一個專案總是會牽涉到多人協作:同學A 寫了函數a(),而同學B 在呼叫函數a() 的時候得一直擼著API 文件才能知道a() 需要什麼參數,會回傳什麼參數。
而同學A 後續又改動了函數a(),但是卻忘了更新文檔,這時候新接手專案的同學C 看著API 文檔和函數a() 一臉懵逼,問題浮現水面:團隊協作中,提供的介面如何描述自身?
這其中涉及的問題有:
1.介面如何描述自己的參數和回傳值?
2.介面參數和回傳值在無數需求迭代中改變了多次,而這個 API 對應的文檔該如3.何更新?
4.資料格式如何描述?
為了解決上述諸多痛點,我們需要引入類型檢查機制,所謂類型檢查,就是在編譯期儘早發現(由類型錯誤引起的)bug,又不影響程式碼運行(不需要運行時動態檢查類型),使編寫js具有和編寫Java等強類型語言相近的體驗,它可以:
#使得大型專案可維護
- ##提高效率,錯誤在寫程式碼時報錯,而非編譯階段
- 增強程式碼的可讀性,可以做到程式碼即文檔
- #增強設計
- 全域安裝flow指令列工具
npm install -g flow-bin
- 在專案根目錄,建立.flowconfig檔
- 安裝babel插件
npm install --save-dev babel-plugin-transform-flow-strip-types
- 在.babelrc檔案中加入外掛程式
{ "presets": [ "es2015", "react", "stage-1" ], "plugins": [ "react-flow-props-to-prop-types" ] }
- 安裝擴充功能(⇧⌘X):Flow Language Support
- 修改VS Code對JavaScript的預設配置
搜尋:javascript. validate.enable
修改為:"javascript.validate.enable": false
- 在專案中使用 ##在需要靜態檢查的檔案頭引入flow,如:
/* @flow */ function getPrice(x: number) { return x * 10; } getPrice('a23') // vscode 工具提示错误
採用typescript
TypeScript 被稱為JavaScript 的超集,是微軟公司推出的靜態程式碼檢查的方案,在JavaScript 上做了一層封裝,封裝出TypeScript 的特性,當然最終程式碼可以編譯為JavaScript
1.靜態型別
let num: number; num = 'likely'; [ts] 不能将类型“"likely"”分配给类型“number”。 let num: number
2.函數表達式
export const fetch = function (url, params, user) { // dosomething return http(options).then(data => { return data }).catch(err => { return err }) }以上下方是一個JavaScript 的函數,所以不看方法內的寫法我們完全不知道這個API 會有哪些坑。
export const fetch = function (url: string | object, params?: any, user?: User): Promise<object | Error> { // dosomething return http(options).then(data => { return data }).catch(err => { return err }) }
export interface CouponProps { coupons: CouponItemModel[]; } export interface couponState { coupons: CouponItemModel[], page: number, size: number, state: number, //可用优惠券 hasMore: boolean, isLoading: boolean, loadedError: boolean, } class CouponContainer extends React.Component<couponprops> { }</couponprops>###上述元件我們可以清楚知道一個元件有哪些屬性,哪些方法,哪些屬性是必傳的,哪些是可選的,一目了然,真正做到了程式碼即文檔###
关于typescript还有很多其他特点,如类,接口,泛型等,具体可参考官方文档
https://www.typescriptlang.org/
项目迁移typescript
1.node
(1)使用npm安装:npm install -g typescript,当前项目使用了是v2.8.3
(2)2.2 tsconfig.json
{ "compilerOptions": { "module": "commonjs", "target": "es5", "noImplicitAny": true, "sourceMap": true, "lib": ["es6", "dom"], "outDir": "dist", "baseUrl": ".", "jsx": "react", "paths": { "*": [ "node_modules/*", "src/types/*" ] } }, "include": [ "src/**/*" ] }
(3)将.js文件改为.ts
(4)结合 gulp 进行实时编译
var gulp = require('gulp'); var pump = require('pump'); var webpack = require('webpack'); var ts = require('gulp-typescript'); var livereload = require('gulp-livereload'); var tsProject = ts.createProject("tsconfig.json"); gulp.task('compile:tsc:server', function () { return gulp.src('src/server/**/*.ts') .pipe(tsProject()) .pipe(gulp.dest('dist/server')); }); //将任务同步执行 var gulpSequence = require('gulp-sequence'); gulp.task('compile', gulpSequence( 'compile:tsc:server', )) gulp.task('watch', ['compile'], function() { livereload.listen(); gulp.watch(['./src/server/**/*.ts'], ['compile:tsc:server']); })
react
可在 webpack 配置文件添加规则
{ test: /\.tsx?$/, enforce: 'pre', use: [ { loader: "ts-loader" } ] },
3.遇到的问题
遇到的问题
动态地为global添加属性
由于js灵活的风格,我们经常动态地为某一对象添加属性,但是typeScript是编译型语言,基本原则是先定义再使用,所以当我们像下面这么引用
global.testName = '哈哈';
便会出现这样的错误
类型“Global”上不存在属性“testName”
解决方法
(1)将global强制转化为any类型 (<any>global).testName = '哈哈' (2)扩展原有的对象 global.prototy.testName = '哈哈哈' (3)使用.d.ts文件</any>
declare namespace NodeJS { export interface Global { testName: string; } }
网上很多方法是直接添加一个.d.ts文件即可,但是亲测无效,需要在引用文件引入该文件,如本项目在app.ts文件中引入了
/// <reference></reference>
Flow 与 TypeScript简单对比
总结
Flow或者TypeScript都是静态类型检查的优秀解决方案,能够给有类型检查需求的一定规模的项目带来实际收益。基于现有项目的情况,迁移 TypeScript 时间成本比较大,学习曲线相对陡峭,建议现有项目采用 Flow 方案,对于一些新的项目,可以采用 TypeScript
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
react 官网动画库(react-transition-group)的新写法
以上是關於react專案靜態類型檢查方案的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

在JavaScript中如何獲取原型鏈上函數的參數在JavaScript編程中,理解和操作原型鏈上的函數參數是常見且重要的任�...

在微信小程序web-view中使用Vue.js動態style位移失效的原因分析在使用Vue.js...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

禪工作室 13.0.1
強大的PHP整合開發環境

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境