發表文章

Typescript 4_ 那些奇怪的字(上) extends, infer, typeof

這篇中途有點難產,畢竟我好像不小心難度拉太高了,所以在思考名詞解釋的情況的時候都是有點不太合適的感覺...另外這些關鍵字詞有 extends, infer, typeof, as, in, keyof, never, unknown, void, static, get, set, readonly,前面會先介紹一部分。 在這篇中,來介紹一下會在typescript看到的關鍵字詞 extends  繼承屬性 extends  的使用上,跟前一篇 & 的使用有那麼一點的類似,不過在typescript的用法更偏向於物件導向的 繼承 / inheritance 的概念。 那...什麼是繼承?就請去找oop相關的書籍,這邊就不再贅述了。畢竟寫oop的前輩對於繼承的相關說明都很透徹了,就無需我再重新解釋:P 有趣的是在typescript的實作中, extends 是可以拿來做 conditional type 來實作的。 也就是可以利用3元表達式  a ? b : c  來對  generic type  做更進一步的屬性判定。 interface IFoo { props: string ; } interface IFooReturn { result: string ; } interface IBar { name: string ; } interface IBarReturn { result: number ; } function Sample < T >( arg: T ): T extends IFoo ? IFooReturn : IBarReturn ; 而  conditional type  搭配  infer  就有各種的實作產生 infer   type inference  取得function裡面的數值 就如字面上的意義來說,這個是常用來取得  function  裡面的參數值,在 typescript 內建函數  utility types  中,可以看到其實作  ReturnType  的內容。 type ReturnType<T extends (...args: any ) => any > = T extends (...ar

Typescript 3 使用,那些奇怪的符號: operators, private, decorator, generic type

本篇會比較強調 typescript 中一些特殊符號,還有>ES6的一些符號,例如說optional chainning,private等的特殊符號。說實話,這篇真的覺得難寫,我不該把範圍開那麼大,不過常用的特殊符號分開來就感覺凌亂,還是寫在一篇我覺得比較好...吧? |   union type  的使用 Union type 使用的時候,即代表參數同時接受  |  兩邊的型別定義,但是注意,他只能符合其中一個型別 let strOrNumber: string | number | undefined ; // 同時接受 string, number, undefined的型別 進階使用方式我常用在撰寫 function 中若有不同的 state,代入的argument也會不同 // 通常出現在 react reducer 的 action 上 type IAction = { type : 'init' // 這些參數甚至可以搭配enum操作 } | { type : 'update' , payload: { arg: string } } | { type : 'disable' , payload: { isShow: boolean ; } } function reducer ( state = initialState, action: IAction ) { // do content switch (action.type) { case 'init' : // no payload break ; case 'update' : action.payload.arg // string type break ; case 'disable' : action.paylaod.isShow // boolean type

Typescript 2 使用 interface,module,namespace,alias type 和簡單提 declare

圖片
在處理typescript宣告型別的中,最常的是先利用interface / type去做基本定義宣告 interface IFoo { bar: string ; } 在這層的關係裡面,只要有宣告 const anything: IFoo 裡面帶的內容就是要照著開出的interface / type去做,要不然會有error而無法正常compile 而重複命名的 interface 型別會進行再對其做屬性擴充 interafce IFoo { something: string ; } interface IFoo { bar: string ; } //same as interface IFoo { something: string ; bar: string ; } 而 type 的情況跟 interface 像但是又有點不一樣 就基本的宣告來說的話 type IFoo = { bar: string ; } 其實對於使用上來說,type和interface差距不大,不過還是有主要的區別的,type可以對已經定義的typescript型別再命名 type alias ,例如說 interface IFoo { bar: string ; } type IFoo2 = IFoo; 這樣就可以對該項型別重新命名了,而有此項功能的type,就可以對相關參數進行更詳細定義 例如說1 / 0這個是在php裡面傳值時也會使用到的boolean型別,既然如此,我就可以將他這樣定義 type IPHPBoolean = 1 | 0 ; 注意, | 這個為typescript2新增的運算子,為 union 的運算子,照上面sample來說,即為 1 或者 0 ,同意 or 。後續會對常用operator再做解說 而 type 要如何進行擴充呢? type IFoo = { bar: string ; }; type IFoo2 = IFoo & { something: string ; }; 如此一來, IFoo2 將 IFoo 進行擴充,也可以使用 something 此項欄位 type 和 interface 使用上差不多,可是如果使用在editor上尤其是

Typescript 1 - basic

跟上次的文章比起來已經很久沒有更新了XD,這次正好算自己回顧一下曾經寫typescript的一些心得吧,另外這系列的文章比較會在於實務上的操作,新手級別的介紹(初入JS的新手們),就麻煩先行去找  mdn  等相關的網站學一下囉。 有寫過javascript的通常都會遇到trace code的時候,到處串api/events/option然後沒有文件,只好在每個點下console.log去查到底會出現什麼。這時候如果改成使用typescript的話,就可以很輕鬆的解決掉這些問題。只要定義好型別,做好pass value的架構,typescript可以協助輕鬆import/restructure/type hint,也是因為這些的好處,讓我越來越不能接受沒有type hint的情況了XD 有興趣的可以看一下 playground 會被compile成什麼樣子 以下就先簡單介紹下typescript常用的一些宣告方式,先用常見的來說明 let str: string ; let num: number ; 如果是以object來進行宣告的話 let foo: { bar: string ; // foo.bar是string type } 這樣在傳值的時候foo就只能接受 {bar: string} 裡面的bar被限制為string type 如果是Array的話 let arr: string [] = ['hello', 'world'] 這樣的 arr 就只能接受 string 型別的資料輸入 此外實務使用上亦有 string literal 和 numeric literal 兩種型別 let str: 'foo' | 'bar' ; let dice: 1 | 2 | 3 | 4 | 5 | 6 ; 如此一來 str 僅能接受 foo 及 bar 的文字,而 dice 同樣只能接受1~6的數字輸入 另外typescript亦有提供 enum 的型別(只有在typescript可以使用到) 至於 enum 是什麼呢? 查wiki大概解釋中文=>列舉...XD enum 其實不會很難,想成是自定

electron --- make a desktop application

現在都在給人家傳教使用electron((X github page 之前的編輯器介紹部分也有做介紹visual studio code, bracket, Atom, 這一系列編輯器base on electron 那就來介紹一下何謂electron吧 把你在網頁上運行的程式碼可以做成桌面APP 只要簡單幾行程式碼,可以達成前後端溝通,底層控制,而且跟網頁執行情況一樣 簡而言之,他就是包含了一個可以進行底層運作的瀏覽器,底層實作是透過nodejs, 渲染畫面則是用了chromium來實作,背後支援團隊是github 原本項目的名稱為atom-shell,之後再改名為electron,目前已經有很多家的企業採用electron為製作desktop application 打著Build cross platform desktop apps with web technologies的electron,其實從之前就有一直關注,我有時會利用它來撰寫一些比較簡易的桌面APP來玩 基本安裝 yarn [global] add electron 因為最新的electron使用node7 的版本,意味著基本的ES6都支援了,連ES7的async/await都可以玩的到 以下是簡易的開啟一個視窗的功能 啊...另外由於我懶得用typescript再重新進行compile過程,所以接下來都是用香草js來進行實作 const { app , BrowserWindow } = require ( 'electron' ); function createWindow () { // 設定寬*高 let mainWindow = new BrowserWindow ({ width: 1024 , height: 768 }); // 將畫面放到最大 mainWindow . maximize () // 主頁面設定,相當於web首頁 mainWindow . loadURL ( 'file://' + __dirname + '/index.html' )

n or nvm a nodejs version manager

這兩個都是nodejs的版本管理工具 不過很可惜的是n無法在windows上使用,而nvm則是要利用nvm-window 額外補充:nodist也是一款在windows尚可運行的管理套件不過我還沒有測試過之後在進行補充 照例 n : github page nvm : github page nvm-window : github page 因為現在工作環境在ubuntu16.04上面,所以我比較常用n來去做我的nodejs版本更新或者返回的動作 另外值得一提的是 n在切換nodejs版本時不會重新設定你的node_modules而nvm會 所以常用的global套件在使用nvm切換版本就得注意要重新安裝,不過當切回版本時global相關又會回來了 還有,在安裝nvm的時候,系統當中必須'沒有'安裝nodejs,nvm才能開始進行初步安裝 如果是使用n就不會有這問題 主要原因是兩者的安裝nodejs方式不同 首先看n安裝的部份 yarn global add n 再來是nvm安裝 (安裝在ubuntu 16.04\) curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash 或者 wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash 一個是裝在global node_modules當中,另外一個則是利用shell script的方式安裝, 如果一開始就有先安裝nodejs的話,在初始進行shell script的階段就會出錯 這點須特別注意 接下來就是指令對照,我只取常用的部份 n lts 安裝或者使用lts版本的nodejs n [version] 安裝或者使用者輸入特定版本號之nodejs version can be latest lts or x.x.x version name nvm install --lts nvm安裝lts版本nodejs nvm install [version] 注意:nvm當安裝

live-server and ngrok

照例: github page 最原本我是使用connect搭配 serve-static 實做 const   connect  =  require ( 'connect' ); const   serveStatic  =  require ( 'serve-static' ); connect (). use ( serveStatic ( __dirname )). listen ( 8080 ,  function (){      console . log ( 'Server running on 8080...' ); }); 主要流程大概就是如此,搭配上 ngrok 大概可以測試個ssl需求的東西 後來從其他地方發現live-server這個好用的東西就拿他來做我暫時性測試和restful api的實做 另外live-server有提供live-reload的功能,只要當前關注的資料夾有異動,會自行reload,不過缺點是並不會clean cached 和 hard reload,這點請注意 一樣起手式 yarn global add live-server 在全域底下安裝live-server live-server [--arguments] 在該資料夾底下直接透過cmd、teminal直接啟動,在指令完成時會啟動default browser然後開啟頁面 沒有做其餘的設定的話,基本出來的url為 http://127.0.0.1:8080/ 如果沒有其他的指令的話,這基本上為固定的預設值,當然接下來就是介紹其他我常用的arguments --port=NUMBER 其實liver-server會自行檢測那一個port被佔用,然後自行尋找新的port --cors 這個提供api可以提供Access-Control-Allow-Origin,拿來做api測試服務很好用 --ignore=PATH || --ignorePattern=REGEX 設定忽略的位置,或者透過regular expression來做設定,這項我通常是放node_modules, package.json的部份 --watch=