做者:Marius Schulz
譯者:前端小智
來源:Marius Schulz
阿里雲雙12
已開啓,新老用戶都可參與,2核1G雲服務器僅需79元
,,更多服務器配置及價格請關注:Hi拼團,或點此瞭解「雲上爆款1折特惠活動」。同時,建議在購買阿里雲相關產品前先領取阿里雲2000元代金券會更優惠哦。前端
爲了保證的可讀性,本文采用意譯而非直譯。git
TypeScript 1.8 引入了字符串字面量類型,用於將變量限制爲可能的字符串值的有限集。在 TypeScript 2.0 中,字面量類型再也不侷限於字符串。如下字面量類型已添加到類型系統中:es6
接下來,來看看這個類型對應的一些事例。github
下面的示例定義了兩個常量 TRUE
和 FALSE
,它們分別持有 true
和 false
值:web
const TRUE: true = true; // OK const FALSE: false = false; // OK
試圖爲每一個局部變量分配相反的布爾值會致使類型錯誤:typescript
const TRUE: true = false; // Error: Type 'false' is not assignable to type 'true' const FALSE: false = true; // Error: Type 'true' is not assignable to type 'false'
隨着 boolean 字面類型的引入,預約義的 boolean 類型如今等價於 true | false
的聯合類型:npm
let value: true | false; // Type boolean
雖然 boolean 字面量類型在隔離時不多有用,但它們與標記聯合類型和基於控制流的類型分析結合使用時很是有效。例如,能夠定義一個泛型 Result <T>
類型,該類型要麼包含一個類型爲 T
的值,要麼包含一個類型爲 string
的錯誤消息,以下所示json
type Result<T> = | { success: true; value: T } | { success: false; error: string };
這是一個接受參數的函數:segmentfault
function parseEmailAddress( input: string | null | undefined ): Result<string> { // 若是 input 爲 null,undefined 或空字符串 //(全部都是虛假的值),就直接返回。 if (!input) { return { success: false, error: "The email address cannot be empty." }; } // 咱們只檢查 input 是否與模式匹配 // <something> @ <something> . <something> // 保持簡單,正確驗證電子郵件地址 if (!/^\S+@\S+\.\S+$/.test(input)) { return { success: false, error: "The email address has an invalid format." }; } return { success: true, value: input }; }
請注意,啓用 strictNullChecks
選項後,string
是不可爲 null
的類型。爲了使函數的 input
參數接受可爲 null
的類型的值,必須在聯合類型中明確包含 null
和undefined
類型。promise
咱們如今能夠像下面這樣調用 parseEmailFunction
:
const parsed = parseEmailAddress("example@example.com"); if (parsed.success) { parsed.value; // OK parsed.error; // Error } else { parsed.value; // Error parsed.error; // OK }
請注意,某些屬性訪問表達式用紅色波浪線下劃線:
這樣作的好處是,編譯器僅在檢查了 parsed.success
後才容許我們使用value
或error
屬性:
parsed.success
爲 true
,則 parsed
的類型必須爲 { success: true; value: string }
。在這種狀況下,我們能夠訪問 value
,但不能訪問 error
。parsed.success
爲 false
,則 parsed
的類型必須爲 { success: false; error: string }
。在這種狀況下,我們能夠訪問 error
,但不能訪問 value
。與字符串字面量類型相似,咱們能夠將數值變量限制爲已知值的有限集
let zeroOrOne: 0 | 1; zeroOrOne = 0; // OK zeroOrOne = 1; // OK zeroOrOne = 2; // 錯誤:類型 '2' 不能分配給類型 '0 | 1'
在實踐中,咱們能夠在處理端口號時使用數字字面量。不安全的 HTTP 使用端口 80
,而 HTTPS 使用端口 443
。我們能夠編寫一個 getPort
函數,並在其函數簽名中編碼僅有的兩個可能的返回值
function getPort(scheme: "http" | "https"): 80 | 443 { switch (scheme) { case: "http": return 80; case: "https": return 443; } } const httpPort = getPort('http'); // Type 80 | 443
若是咱們將字面量類型與 TypeScript 的函數重載結合起來,那就更有趣了。這樣,咱們能夠爲 getPort
函數的不一樣重載提供更具體的類型。
function getPort(scheme: "http"): 80; function getPort(scheme: "https"): 443; function getPort(scheme: "http" | "https"): 80 | 443 { switch (scheme) { case "http": return 80; case "https": return 443; } } const httpPort = getPort("http"); // Type 80 const httpsPort = getPort("https"); // Type 443
如今,當返回的時候與比較的值永遠都不會相同的狀況下,編輯器會提示咱們,例如,將 httpPort
與值 443
進行比較時:
因爲 httpPort
的類型爲 80
,所以它始終包含值 80
,該值固然永遠不會等於值 443
。在這種狀況下,TypeScript 編譯器能夠幫助我們檢測錯誤的邏輯和無效的代碼。
最後,我們還可使用枚舉做爲字面量類型。繼續前面的示例,實現一個給定端口(80
或443
)映射到相應方案(分別爲 HTTP
或 HTTPS
)的函數。爲此,咱們首先聲明一個const enum
,它對兩個端口號進行構建:
const enum HttpPort { Http = 80, Https = 443 }
如今是 getScheme
函數,再次使用函數重載來實現專門的類型註解:
function getScheme(port: HttpPort.Http): "http"; function getScheme(port: HttpPort.Https): "https"; function getScheme(port: HttpPort): "http" | "https" { switch (port) { case HttpPort.Http: return "http"; case HttpPort.Https: return "https"; } } const scheme = getScheme(HttpPort.Http); // Type "http"
常量枚舉沒有運行時表現形式(除非提供了preserveConstEnums
編譯器選項),也就是說,enum
用例的常量值將被內聯到使用它們的任何地方。下面是通過編譯的 JS 代碼,去掉了註解:
function getScheme(port) { switch (port) { case 80: return "http"; case 443: return "https"; } } var scheme = getScheme(80);
是否是超級簡潔?
TypeScript 2.0 讓我們以更細粒度地控制項目中包含哪些內置 API 聲明。之前,只有在的項目配置 ES6 相關的包才能訪問 ES6 Api
。如今,內置的標準庫聲明已經模塊化,TypeScript 容許咱們選擇包含哪一種類型聲明。
JS 標準庫的類型聲明被劃分爲一組 API 組。 2016 年 11 月下旬撰寫本文時,定義瞭如下組
能夠經過 --lib
命令行選項或 tsconfig.json
中的 lib
屬性將上述組的任何子集傳遞給TypeScript 編譯器。TypeScript 將只注入你指定的類型;也就是說,它會將全部其餘 API 組視爲不存在於你的的環境中。
若是未明確提供 lib
選項,則 TypeScript 將隱式注入Web開發所需的API組。
注意:若是--lib
沒有指定默認庫。默認庫是
["dom", "es5", "scripthost"]
["dom", "es6", "dom.iterable", "scripthost"]
假設你正在處理一個 target
爲 es5
項目,爲了讓它能在全部主流瀏覽器中運行。你的tsconfig.json
多是這樣的:
{ "compilerOptions": { "module": "commonjs", "target": "es5", "noImplicitAny": true, "strictNullChecks": true } }
由於 lib
選項沒有指定,因此默認狀況下 TypeScript 會注入 API 組 "dom"
、"es5"
和"scripthost"
。如今但願在項目中使用ES6 中原生的 Pormise
。這些在 ES5 中並無,因此我們須要安裝一個 polyfill
來讓咱們的代碼在舊的瀏覽器中運行:
npm install --save es6-promise
而後能夠在入口文件中導入對應的庫
import "es6-promise";
有了這個 polyfill,如今就能夠在應用程序中使用 Promise
,代碼也能夠正常運行。然而,TypeScript 會給你一個編譯時錯誤: Cannot find the name 'Promise'
。這是由於 Promise
的類型聲明不包含在任何注入的 API 組中。
咱要讓 TypeScript 知道 Promise
會在運行時存在,這就是 lib
編譯器選項發揮做用的地方:
注意,一旦覆蓋了默認值,就必須顯式地提供全部API組,以下所示:
{ "compilerOptions": { "module": "commonjs", "target": "es5", "noImplicitAny": true, "strictNullChecks": true, "lib": ["dom", "es5", "es2015.promise"] } }
如今編輯器就不會在報錯了:
編輯中可能存在的bug無法實時知道,過後爲了解決這些bug,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:
https://mariusschulz.com/blog...
https://mariusschulz.com/blog...
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq449245884/xiaozhi
由於篇幅的限制,今天的分享只到這裏。若是你們想了解更多的內容的話,能夠去掃一掃每篇文章最下面的二維碼,而後關注我們的微信公衆號,瞭解更多的資訊和有價值的內容。