為什么需要引入類型檢查?
JS作為一個弱類型語言,一個著名的黑點是它很容易就寫出非常隱蔽的隱患代碼,在編譯期甚至運行時看上去都不會報錯,但是可能會發(fā)生各種各樣奇怪的和難以解決的bug。
所謂類型檢查,就是在編譯期盡早發(fā)現(xiàn)(由類型錯誤引起的)bug,又不影響代碼運行(不需要運行時動態(tài)檢查類型),使編寫js具有和編寫Java等強類型語言相近的體驗。它可以:
1、使得大型項目可維護(hù)
2、增加代碼的可讀性
3、通常會有更好的IDE支持
什么是Flow
Flow是一個由Facebook出品的JavaScript靜態(tài)類型檢查工具,它與Typescript不同的是,它可以部分引入,不需要完全重構(gòu)整個項目(需要進(jìn)行類型檢查的文件加上//@flow 注釋),所以對于一個已有一定規(guī)模的項目來說,遷移成本更小,也更加可行。除此之外,F(xiàn)low可以提供實時增量的反饋,通過運行Flow server不需要在每次更改項目的時候完全從頭運行類型檢查,提高運行效率
基本形式
// @flow
function square(n:number):number{
return n*n;
}
square("2");// Error!
安裝與配置
安裝
yarn add --dev flow-bin //最好安裝項目文件.flowconfig中要求的版本
運行檢查
yarn flow
安裝flow-type(導(dǎo)入第三方類型的工具)
yarn add --dev flow-type
運行flow-typed
yarn flow-typed install module_name
webstorm中配置
配置好之后在所有有//@flow注釋的文件都會進(jìn)行監(jiān)視
.flowconfig修改
在[options]里加上
esproposal.decorators=ignore //忽略裝飾符
module.system.node.resolve_dirname=./src //允許在src里查找模塊
module.system.node.resolve_dirname=node_modules
在React的應(yīng)用:
1、mobx的最佳實踐
定義store:
AppStore.js
//@flow
import { observable, action, runInAction, configure }from 'mobx'
class appStore {
@observable
isLoading: boolean =false
@loading
@action
async login(user: {userName: string, password: string }) {
const {accessToken, userId } =await TokenAuthService.authenticate({
model: {
userNameOrEmailAddress: user.userName,
password: user.password
}
})
await setStorageValue('Authorization', accessToken)
return userId
}
}
export default appStore
使用Store:
Login.js
//@flow
import React, {Component }from 'react'
import {StyleSheet, View }from 'react-native'
import type AppStore from '../../store/AppStore'
type Props = {
appStore: AppStore
}
class App extends Component <Props>{
render() {
//test
this.props.appStore.login({user:"userName",password:"123456"})
return (
<View></View>
)
}
}
這種使用方式可以使得在調(diào)用this.props.appStore.時,webstorm能知道appStore的所有屬性和方法,從而自動給出提示
2、變量為第三方類型時
以react-navigation為例:
使用:
yarn flow-typed install react-navigation
自動生成flow-typed文件夾,在npm子文件夾里創(chuàng)建了一個類型文件react-navigation_v2.x.x.js,里面是react-navigation一些方法屬性的聲明,調(diào)用的時候:
import type {NavigationScreenProp} from 'react-navigation'
之后
type Props{
navigation :NavigationScreenProp<*>
}
調(diào)用
const {push}=this.props.navigation
push&&push('otherScreen')
注意push(),pop()等等這些方法如果不寫undefine判斷,flow會報錯,因為在type文件里這些方法是有加問號?的,表明可以為undefine,flow為了防止調(diào)用未定義的方法所以報錯