// TypeScript 是JavaScript的「超集」 //前端
// 前端語言中冉冉升起的新星 //編程
TypeScript是一種由微軟開發的、開源的編程語言,近兩年發展迅猛,愈來愈多的JavaScript項目正在遷移到TypeScript,主流前端框架及Node.js對TypeScript的支持也愈來愈友好。自2012年10月發佈首個公開版本以來,它已獲得了人們的普遍承認。json
TypeScript發展至今,已經成爲不少大型項目的標配,其提供的靜態類型系統,大大加強了代碼的可讀性及可維護性;同時,它提供最新的和不斷髮展的JavaScript特性,能讓咱們構建更健壯的組件。安全
然而在TypeScript中,有些地方對「開箱即用」進行了限制,例如當使用一個未被聲明過的變量時(固然,你能夠爲外部系統使用聲明文件)。也就是說,傳統的編程語言在類型系統容許與不容許之間存在明顯的邊界。前端框架
TypeScript不一樣於傳統的編程語言,它可讓你本身設置類型系統的邊界。這其實是爲了讓你可以使用你喜歡的JavaScript,並儘量安全地使用它。前端工程師
在TypeScript中,有不少選項均可以精確地控制此邊界,下文選自**《深刻理解TypeScript》**一書,如今就讓咱們去了解它們吧。框架
▼▼▼編程語言
選項爲boolean的compilerOptions,能夠被指定爲tsconfig.json下的compilerOptions。函數
{ "compilerOptions": { "someBooleanOption": true } }
或者使用命令行。工具
tsc --someBooleanOption
▼▼▼
有些代碼沒法被推斷,或者推斷它們可能會致使意外的錯誤。一個很好的例子就是函數參數,若是沒有對它們進行註解,那麼你將不清楚哪些是有效的。
functionlog(someArg) { sendDataToServer(someArg); } // 參數是什麼,下面哪一個是不正確的 log(123); log('hello world');
所以,若是你沒有註解函數的參數,TypeScript將會認爲它是any類型的,並將繼續執行。在這種狀況下,將會關閉類型檢查,這是JavaScript開發人員所指望的。可是這可能會讓那些對安全性要求較高的人措手不及。所以,這裏有一個noImplicitAny選項,當開啓這個選項時,它將會標記沒法被推斷的類型的狀況,以下所示。
functionlog(someArg) {// 錯誤:someArg是any類型的 sendDataToServer(someArg); }
固然,你能夠繼續進行註解。
functionlog(someArg: number) { sendDataToServer(someArg); }
若是真的想拋棄安全性,你能夠把它標記爲any。
functionlog(someArg: any) { sendDataToServer(someArg); }
▼▼▼
在默認狀況下,null和undefined能夠被賦值給TypeScript中的全部類型。
let foo: number = 123; foo = null; // 能夠 foo = undefined; // 能夠
這順應了大多數編寫JavaScript的人的習慣。可是,同時TypeScript容許你明確指出能夠分配給null/undefined的內容。
在嚴格的null檢查模式下,null和undefined是不一樣的。
let foo = undefined; foo = null; // 不能夠
假設有一個接口Member,以下所示。
interface Member { name: string, age?: number }
並非全部的Member都會提供年齡,因此age是一個可選屬性,也就是說age的值可能爲undefined。
undefined是「萬惡之源」,它一般會致使運行時錯誤。(編寫在運行時拋出錯誤的代碼很容易。)
getMember() .then(member: Member =>{ conststringifyAge = member.age.toString() //toString屬性可能undefined })
可是在嚴格的null檢查模式下,這個錯誤將會在編譯時被捕獲。
getMember() .then(member: Member =>{ conststringifyAge = member.age.toString() // 對象可能undefined })
在一個類型檢查沒法得出結論的上下文中,一個新的!表達式後綴操做符,能夠用來斷言運算對象是非null和非undefined的,示例以下。
// 用--strictNullChecks進行編譯 functionvalidateEntity(e?: Entity) { // 若是e是null或其餘無效的實體,則拋出錯誤 } functionprocessEntity(e?: Entity) { validateEntity(e); let a = e.name; // 錯誤:e多是null let b = e!.name; // 能夠,咱們已經斷言e是非null }
注意,它只是一個斷言,就像類型斷言同樣,你須要確保該值不爲空。一個非null的斷言實質上意味着你在告訴編譯器「我知道它不是null,可是請讓我使用它,即便它不是null」。
TypeScript將會對類中未初始化的屬性拋出錯誤。
class C { foo: number; // 能夠,已經在構造器中初始化 bar: string = "hello"; // 能夠,已經初始化 baz: boolean; // 錯誤:屬性baz沒有初始化,也沒有在構造器中被賦值 constructor() { this.foo = 42; } }
你可使用明確賦值斷言,在屬性名後加後綴,來告訴TypeScript你已經在其餘地方(不是在構造器中)對它進行了初始化。
class C { foo!: number; // 注意這個感嘆號 // 這是明確賦值斷言操做符 constructor() { this.initialize(); } initialize() { this.foo = 0; } }
你也能夠將此操做符與變量聲明一塊兒使用。
let a: number[]; // 沒有斷言 let b!: number[]; // 斷言 initialize(); a.push(4); // 錯誤:變量在賦值以前被使用 b.push(4); // 能夠:由於被斷言 functioninitialize() { a = [0,1,2,3]; b = [0,1,2,3]; }
就像全部的斷言同樣,你在告訴編譯器讓它相信你,讓編譯器再也不拋出錯誤,即便代碼並無被分配屬性。
做爲JavaScript的「超集」,TypeScript靜態類型檢查讓咱們能輕鬆地構建和維護大型的前端項目。《深刻理解TypeScript》一書是 TypeScript Deep Dive 的中文版,全面闡述了TypeScript的各類「魔法」,示例豐富,簡單易懂,而且對初學者很是友好!
本書從實際應用場景出發,對TypeScript語言進行深度剖析,並結合代碼示例講解了諸多TypeScript高級編程技巧,以及在實際開發工做中的最佳實踐方案,能幫助讀者更加透徹地理解TypeScript。
█ 與官方文檔相比,本書主要有如下幾個特色
█ 關 於 做 譯 者
Basarat Ali Syed
TypeScript專家,微軟JavaScript/TypeScript的MVP貢獻者。他是TypeScript社區受人尊敬的成員,澳洲Picnic software高級開發人員,在DefinitelyTyped團隊工做。Basarat常常參加澳大利亞與前端開發技術有關的會議,在多個技術活動中作過演講。Basarat還著有Beginning Node.js 一書,目前該書已被下載39000屢次,在亞馬遜、豆瓣等平臺獲得了讀者的一致好評。
郭文超:TypeScript深度愛好者,經常使用筆名三毛,公衆號 FENews 主要維護者。曾在 TutorABC、eBay 任職,目前在千尋位置擔任前端工程師。對 TypeScript、React、Vue 等有較深理解。
何小磊:山西能快科貿CTO,有十年以上軟件開發經驗。
柳星:TypeScript 重度用戶,經常使用網名 S1ngS1ng,是 freeCodeCamp 中文社區的維護者之一。曾在 Rackspace、VMware、Apple 任前端工程師一職。
徐野:攜程AI研發部前端工程師。熱愛大前端,愛折騰新鮮技術,精通 TypeScript、React、Node 等前端技術。
█ 目 錄 結 構
本文由博客一文多發平臺 OpenWrite 發佈!