typescript最大的賣點對於我來講就是類型檢查和IDE提示的快感了,之前我是抗拒用ts的,由於感受它加入了太多東西了,又要新學不少東西,可是呢如今貌似ts是個大勢所趨,我最喜歡的框架vue都要用ts重構了,so,向ts前進吧!javascript
我用rn開發了一個項目後,就火燒眉毛的準備在下個項目中開始介入ts了,可是完事開頭難,遇到了好多問題,主要在配置上...我本身想了辦法解決,可是感受不完美,但願掘金ts大佬指導下,另外react-native的坑在上個項目也讓我見識了,不是通常的多,怪不得如今還沒發佈1.0版本,可是也沒辦法,跨端項目自己就及其負責,有時間總結下rn的坑.html
初始化react-native按照官網的教程,本身踩坑哈,接下來成功運行後,開始改形成ts,教程按照微軟的這個教程
TypeScript-React-Native-Startervue
完成後出現了兩個我暫時解決的問題java
react-native中有個全局的global對象,相似web中的window,有時候我會想往global上放一個全局的方法或者變量,怎麼作呢?react
我安裝的@types/react-native
是0.57.0版本,而後我再代碼中輸入
`
global.time=33
`
這時候編譯器老是提示Error:(25, 3) TS2304: Cannot find name 'global'.
wfk? 疑問來了,我點開@types/react-native/index.d.ts明明看到了git
... declare global { function require(name: string): any; } ...
這個問題搞了我很久了,github 一開始我覺得是bug就去github搜搜issues發現沒有,因而提了個issues,但願有迴應,可是得想個辦法解決:
首先在 本身的src目錄新建一個文件夾typings,用來放本身的類型聲明文件新建一個global.d.ts,名字隨便起,我以前以爲是隻能叫這個,而後在裏面寫以下代碼程序員
declare module global{ let name:string; let time:Time; let dp:(px:number)=>number; let font:(px:number)=>number; }
而後就能夠在代碼中使用了,看圖github
回覆就是 web
It isn't a good practice to use this global keyword, but it exists and should be present in react-native context.
嗯不是最佳實踐,可是有時候真的須要啊就像window對象,有時候仍是須要掛在東西給它的,而後咱們在源碼也能夠看到他們添加了globaltypescript
那上面的問題就看他們何時發佈新代碼了,不過也算學習了。另外說個個人疑問
源碼中是用
declare global{ function require(name: string): any; /** * Console polyfill * @see https://facebook.github.io/react-native/docs/javascript-environment.html#polyfills */ interface Console { error(message?: any, ...optionalParams: any[]): void; info(message?: any, ...optionalParams: any[]): void; log(message?: any, ...optionalParams: any[]): void; warn(message?: any, ...optionalParams: any[]): void; trace(message?: any, ...optionalParams: any[]): void; debug(message?: any, ...optionalParams: any[]): void; table(...data: any[]): void; disableYellowBox: boolean; ignoredYellowBox: string[]; } }
直接declare global是什麼意思?通常不都是declare namespace ,declare module,declare function等等麼
2018.10.29更新,我在githut issues看到了這個問題 他們討論結果貌似是這是一個bug?可能會在ts3.2修復?
請自行看一下
https://github.com/DefinitelyTyped/DefinitelyTyped/issues/29265
我看到微軟那個教程上寫樣式是這麼寫的
// styles const styles = StyleSheet.create({ root: { alignItems: "center", alignSelf: "center" } })
嗯完美,沒問題,但是我本身寫個就報錯了
// styles const styles = StyleSheet.create({ welcome: { fontSize: 20, textAlign: 'center', margin: 0, } });
Error:(42, 11) TS2322: Type 'RegisteredStyle<{ fontSize: number; textAlign: string; margin: number; }>' is not assignable to type 'StyleProp<TextStyle>'. Type 'RegisteredStyle<{ fontSize: number; textAlign: string; margin: number; }>' is not assignable to type 'RecursiveArray<false | TextStyle | RegisteredStyle<TextStyle>>'. Property 'length' is missing in type 'Number & { __registeredStyleBrand: { fontSize: number; textAlign: string; margin: number; }; }'.
意思就是類型不對,解決辦法
type Style={welcome:TextStyle}// 定義一個別名 // styles const styles = StyleSheet.create<Style>({ welcome: { fontSize: 20, textAlign: 'center', margin: 0, } });
可是這樣寫好麻煩啊,並且我參考的文章別人都沒有在這裏傳入類型,後來翻了翻github 貌似有人說這是新版本纔有這個問題的,因此我還不知作別人怎麼解決的,我先這麼寫吧,
我想能不能定義一個全局的Style別名或者接口呢?每一個頁面直接用就行了
一樣的我在global.d.ts這麼寫
import {ViewStyle} from "react-native"; interface Style{ [prop:string]:ViewStyle }
這麼一寫不知道爲何沒法識別global這個變量了,提示找不到,我把導入語句刪了就沒事了這是爲何?真的須要大佬幫忙解釋了。
怎麼寫路徑別名?
我在百度一頓搜索,好吧,還真的有 babel-plugin-root-import
,這裏有兩個問題要解決
奔着這個思路,我兩個都配置好了,發現始終沒法讓babel識別,老是報錯找到不到模塊
配置大概這樣子
// .babelrc { "env": { "production": { "plugins": [ "transform-remove-console",[ "babel-plugin-root-import", { "paths":[ { "rootPathSuffix": "src", "rootPathPrefix": "@src" }, { "rootPathSuffix": "./src/components", "rootPathPrefix": "@components" } ] } ] ] } }, "presets": ["module:metro-react-native-babel-preset"], "plugins": [[ "babel-plugin-root-import", { "paths":[ { "rootPathSuffix": "src", "rootPathPrefix": "@src" }, { "rootPathSuffix": "./src/components", "rootPathPrefix": "@components" } ] } ]] }
我這個配置我感受沒錯,按照插件文檔寫的如出一轍,可是依舊不行,難道我寫錯了嗎?
不過最終我放棄了,由於我最新版本的react-native已經使用了一個叫react-native-typescript-transformer
的工具在編譯時自動轉換ts爲js,從前聽說用ts寫rn要先用ts編譯器轉換成js,而後再讓rn 讀取轉換後的代碼,這個開發體驗很很差啊,如今有了這個,不用再單獨去轉js了,不過我以爲有個很差的,就是它只轉換ts不檢查類型錯誤,也就是你類型不對照樣能運行,關於這個github也有討論,我大概看過,貌似意思是故意而爲之,我仍是但願直接報錯,別運行,如今只能藉助ide提示了,接着說那個問題,我在這個工具的文檔上發現了個說明
剛開始沒認真看啊,畢竟英語,後來仔細看了看原來是用這個工具能夠配置別名,可是方法有點奇怪
大概意思是在你想要起別名的文件夾裏面新建一個package.json文件,裏面寫個name屬性叫你配置的別名,這個別名要跟tsconfig配置的一直
好比我在tsconfig配置個路徑別名
"baseUrl": ".", //注意這個必定要配置,否則paths沒用 "paths": { "@components/*":["src/components/*"] },
接下來我要在components文件夾新建一個package.json
{ "name":"@components" }
這樣再運行,終於跑起來了,同時ts能識別了,厲害的是ws也能跳轉了,以前在vue中配置別名,ws是不識別的
我會持續更新這個文章,保持踩坑,但願有大佬看到我上面的問題來評論交流下啊,另外接觸react-native後我深入的感覺到github issues的強大和英語能力的需求,我遇到的rn的坑大部分我只須要把報錯在rn的issues一搜索就能搜到,可是都是英語,因此程序員真的須要提升英語閱讀能力哦,最後再說句,rn的新版本不要當即用,100%有坑,若是能力強能夠先踩坑,另外遇到問題了,不要慫,提issues,用有道詞典翻譯一下大體就能說明白了,個人好幾個問題都是提issues解決的最後。emmm,夜深了,晚安!