Typescript初識及初步實踐週報

caozheng550發表於2019-02-16

初識typescript

Typescript算是最近比較流行的“語言”(強語言型別檢測),有利於編寫大型程式。strong typing貌似現在很多人比較認可。例如現在比較流行的Go以及新近的Kotlin。也是因為最近在使用antd而接觸到,Angular2用的可能比較多。
TypeScript是一種由微軟開發的自由和開源的程式語言。它是JavaScript的一個超集(ES6的超集),而且本質上向這個語言新增了可選的靜態型別和基於類的物件導向程式設計。
如果說只是簡單的認為TS(Typescript以後用縮寫TS來表示)是ES6的超集更趨進於ES8這種理解,在我看來是不對的。(原因後面再說 -。- 踩坑血淚史)。

為什麼Typescript會火

  • 前端發展的必然趨勢

前端最近幾年成井噴式發展,mvc、mvvm、mvp各種框架層出不窮,但是就是這種井噴式的發展給前端注入了一些新的活力,前端未來的發展趨勢也是逐漸的趨於規範化,遙想當年java不也經歷過這麼一段“動盪”的時期麼。而javascript本身就是一個弱語言無法和java這種強語言型別進行比較,但是一個強語言型別帶來的優勢又是如此的鮮明–健壯、易維護…(幹嘛讓我寫這麼全~我又不是搞java的-。-)那麼問題來了怎麼才能圓jser的這麼一個夢想呢?Typescript!雖然我不能保證Typescript能夠長久的活下去但是在我看來這個思路是對的!

例項

這裡就不詳細展開typescript的文件了,舉個TS比較常用的例子。

interface TableProps<T>{
    prefixCls?: string;
    dropdownPrefixCls?: string;
    rowSelection?: TableRowSelection<T>;
    pagination?: PaginationProps | boolean;
    size?: `default` | `small`;
    dataSource?: T[];
    columns?: ColumnProps<T>[];
    rowKey?: string | ((record: T, index: number) => string);
    ...
}

定義了一個TableProps介面規範–用來檢測當前使用props是否符合規範,可以理解為React中的propTypes型別校驗。其中還使用了<T>泛型。
如果想深入研究TS的話,可以直接訪問Typescript官網,這裡不做贅述。

實踐

TS為了相容jsx專門實現了tsx的檔案,可以更方便的使用React。

  • 使用ES6、ES7語法

當然babel已經可以解析ES6、ES7語法babel polyfill,但是如果使用typescript的編譯tsx/ts的時候使用的ts-loader或者awesome-typescript-loader,必須將tsconfig.json
lib新增需要的解析的語法,否則TS會檢測出錯。

{
  "compilerOptions": {
    "moduleResolution": "node",
    "module": "commonjs",
    "target": "es6",
    "sourceMap": true,
    "allowSyntheticDefaultImports": true,
    "jsx": "react",
    "lib": [
      "dom",
      "es2015.promise",
      "es5",
      "es2015.iterable",
      "es2015.generator",
      "es2015.symbol",
      "es7"]
  },
  "exclude": [
    "node_modules"
  ]
}

這個並不算完,因為這裡設定target為ES6–編譯後的js為ES6。如果需要編譯成ES5那麼ts將不會把ES6中 Generator 和ES7語法中的async await編譯成ES5。如果想將其編譯成ES5的話那麼就需要在loader中加入babel-loader。如:(使用webpack2語法)

{
                test: /src\pages(\.*).(tsx|ts)/,
                use: [
                    `bundle-loader?lazy`,
                    `babel-loader`,
                    `ts-loader`,
                ],
},

同時typescript作者將在2.3 (May 2017) Generator support for ES3/ES5

  • 關於ts中全域性變數/函式的定義及使用

使用場景:想在所有ts/tsx中引用一個輔助函式。(使用import太麻煩而且使用頻率很高)。
解決方案(不完整)
1、webpack(Resolve alias)
建立全域性變數別名,編寫時直接引用,交給webpack解析。
2、釋出一個npm,同時建立d.ts檔案用來宣告
@types/whatwg-fetch是使用的這種方案,編寫中可以直接引用fetch,TS會檢測到對應宣告的d.ts檔案,從而不會報錯。
3、掛在到window
例如:encodechar -> 全域性
建立一個global.d.ts檔案,在其中宣告declare const encodechar: string;

  • d.ts檔案

這個算是一個小缺陷吧(這需要時間和積累),主流的框架或者外掛是有@type的實現,但是很多小的框架是沒有對應TS版本的,導致了很多小玩意在ts中玩不了,如果想玩需要用一些黑科技(自己宣告一個d.ts版本….)舉一個例子:
如果想使用import { bindActionCreator } from ‘redux’;
在TS檢測是不通過的因為它沒有實現bindActionCreator的宣告,所以一個黑暗的解決方案出現了,就是自己封裝了一個bindActionCreator同時寫一個d.ts檔案給TS進行識別。

弊端

說一下TS使用中的一些感覺不好的地方吧(用的比較淺顯,純屬個人看法)。
1、d.ts檔案要和js一樣不斷的進行同步迭代,否則會導致新加的介面報錯。
2、增加了學習的複雜度,對於沒有接觸過C#,JAVA…來說,也是需要一點時間來接受的。
3、相對於React來說有點重合(純屬個人看法),因為React中也有props的型別檢測,當然TS是一個全域性的檢測,不是一個量級的。
4、國內沒有大範圍使用,如果踩坑十分痛苦。
5、另外再說一下antdtsx結合使用稍微會比jsx痛苦一點。(有些d.ts檔案沒有跟上迭代)例如:
antd V2.6.3
在Pagination.d.ts中

showTotal?: (total: number) => React.ReactNode;

沒有第二個引數,但是原始碼中是有的。所以如果想使用只能人工新增TS才不會報錯

showTotal?: (total: number, range?: [number,number]) => React.ReactNode;    

相關文章