TypeScript Type Innference(類(lèi)型判斷)
TypeScript 是微軟開(kāi)發(fā)的 JavaScript 的超集,TypeScript兼容JavaScript,可以載入JavaScript代碼然后運(yùn)行。TypeScript與JavaScript相比進(jìn)步的地方 包括:加入注釋?zhuān)尵幾g器理解所支持的對(duì)象和函數(shù),編譯器會(huì)移除注釋?zhuān)粫?huì)增加開(kāi)銷(xiāo);增加一個(gè)完整的類(lèi)結(jié)構(gòu),使之更新是傳統(tǒng)的面向?qū)ο笳Z(yǔ)言。
為什么會(huì)有 TypeScript?
JavaScript 只是一個(gè)腳本語(yǔ)言,并非設(shè)計(jì)用于開(kāi)發(fā)大型 Web 應(yīng)用,JavaScript 沒(méi)有提供類(lèi)和模塊的概念,而 TypeScript 擴(kuò)展了 JavaScript 實(shí)現(xiàn)了這些特性。TypeScript 主要特點(diǎn)包括:
TypeScript 是微軟推出的開(kāi)源語(yǔ)言,使用 Apache 授權(quán)協(xié)議
TypeScript 是 JavaScript 的超集.
TypeScript 增加了可選類(lèi)型、類(lèi)和模塊
TypeScript 可編譯成可讀的、標(biāo)準(zhǔn)的 JavaScript
TypeScript 支持開(kāi)發(fā)大規(guī)模 JavaScript 應(yīng)用
TypeScript 設(shè)計(jì)用于開(kāi)發(fā)大型應(yīng)用,并保證編譯后的 JavaScript 代碼兼容性
TypeScript 擴(kuò)展了 JavaScript 的語(yǔ)法,因此已有的 JavaScript 代碼可直接與 TypeScript 一起運(yùn)行無(wú)需更改
TypeScript 文件擴(kuò)展名是 ts,而 TypeScript 編譯器會(huì)編譯成 js 文件
TypeScript 語(yǔ)法與 JScript .NET 相同
TypeScript 易學(xué)易于理解
語(yǔ)法特性
類(lèi) Classes
接口 Interfaces
模塊 Modules
類(lèi)型注解 Type annotations
編譯時(shí)類(lèi)型檢查 Compile time type checking
Arrow 函數(shù) (類(lèi)似 C# 的 Lambda 表達(dá)式)
JavaScript 的 TypeScript 的區(qū)別
TypeScript 是 JavaScript 的超集,擴(kuò)展了 JavaScript 的語(yǔ)法,因此現(xiàn)有的 JavaScript 代碼可與 TypeScript 一起工作無(wú)需任何修改,TypeScript 通過(guò)類(lèi)型注解提供編譯時(shí)的靜態(tài)類(lèi)型檢查。TypeScript 可處理已有的 JavaScript 代碼,并只對(duì)其中的
TypeScript 代碼進(jìn)行編譯。
在這一節(jié),我們將介紹TypeScript中的類(lèi)型推斷。我們將會(huì)討論類(lèi)型推斷需要在何處用到以及如何推斷。
基礎(chǔ)
在TypeScript中,在幾個(gè)沒(méi)有明確指定類(lèi)型注釋的地方將會(huì)使用類(lèi)型推斷來(lái)提供類(lèi)型信息。
var x = 3;
變量"x"的值被推斷為number。這種推斷發(fā)生在變量或者成員初始化、設(shè)置參數(shù)默認(rèn)值、決定函數(shù)返回類(lèi)型的時(shí)候。
最佳公共類(lèi)型
當(dāng)需要從多個(gè)表達(dá)式中進(jìn)行類(lèi)型推斷的時(shí)候,這些表達(dá)式的類(lèi)型將會(huì)用來(lái)推斷出一個(gè)"最佳公共類(lèi)型"。例如:
var x = [0, 1, null];
要想推斷出什么例子中"x"的類(lèi)型,我們需要考慮每個(gè)數(shù)組元素的類(lèi)型。這里,我們給出了兩個(gè)數(shù)組類(lèi)型的選擇:number和null。最佳公共類(lèi)型算法要求考慮到所有候選的類(lèi)型,并選擇出與所有候選類(lèi)型兼容的類(lèi)型。(這里的類(lèi)型可為Array<number>)
由于最佳公共類(lèi)型是從提供的候選類(lèi)型中選擇的,有些情況下,候選類(lèi)型共享一個(gè)共同類(lèi)型,但沒(méi)有任何一個(gè)類(lèi)型是所有候選類(lèi)型的父類(lèi)型。例如:
class Animal { name:string; constructor(theName: string) { this.name = theName; } } class Snake extends Animal{ constructor(name: string) { super(name); } } class Elephant extends Animal{ constructor(name: string) { super(name); } } class Rhino extends Animal { constructor(name: string) { super(name); } } var zoo = [new Rhino(), new Elephant(), new Snake()]; // 這里三個(gè)成員的類(lèi)型分別為:Rhino、Elephant、Snake 他們是最佳公共類(lèi)型的候選類(lèi)型,Animal是他們的super type(譯為父類(lèi)型)
理想情況下,我們可能希望zoo被推斷為Animal[]類(lèi)型,但是因?yàn)閿?shù)組中沒(méi)有任何對(duì)象是嚴(yán)格的Animal類(lèi)型,我們便不能做出推斷。為了解決這個(gè)問(wèn)題,當(dāng)不能推斷出所有候選類(lèi)型的父類(lèi)型的時(shí)候,我們需要明確的提供類(lèi)型。
var zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];
當(dāng)沒(méi)有最佳公共類(lèi)型的時(shí)候,推斷的結(jié)果是產(chǎn)生一個(gè)空對(duì)象,{}。因?yàn)檫@個(gè)類(lèi)型不含任何成員,對(duì)于其任何屬性的訪問(wèn)都會(huì)導(dǎo)致錯(cuò)誤。這種結(jié)果依然允許我們?cè)诤雎灶?lèi)型的方式中使用對(duì)象,但在保障類(lèi)型安全的前提下,該對(duì)象的類(lèi)型不能被隱式的確定。
上下文(語(yǔ)境)類(lèi)型
在TypeScript中,類(lèi)型推斷在某些情況下也存在于"其他方面"。這被稱為"上下文歸類(lèi)"。上下文歸類(lèi)發(fā)生在當(dāng)一個(gè)表達(dá)式的類(lèi)型在其所在的上下文中被隱式的指定的時(shí)候。例如:
window.onmousedown = function(mouseEvent) { console.log(mouseEvent.buton); //<- 編譯時(shí)拋出錯(cuò)誤 };
上面的代碼將會(huì)給出一個(gè)類(lèi)型錯(cuò)誤,TypeScript的類(lèi)型檢查器使用Window.onmousedown函數(shù)的類(lèi)型來(lái)推斷右邊的函數(shù)表達(dá)式類(lèi)型。當(dāng)它這么做的時(shí)候,便能夠推斷出參數(shù)mouseEvent的類(lèi)型。 如果這個(gè)表達(dá)式不在可進(jìn)行上下文歸類(lèi)的位置,參數(shù)mouseEvent 需要給定一個(gè)any類(lèi)型,這樣就不會(huì)出現(xiàn)錯(cuò)誤了。
如果需要上下文歸類(lèi)的表達(dá)式內(nèi)容中包含明確的類(lèi)型信息,則會(huì)忽略上下文歸類(lèi)。我們重寫(xiě)上面的例子:
window.onmousedown = function(mouseEvent: any) { console.log(mouseEvent.buton); //<- 現(xiàn)在不會(huì)報(bào)錯(cuò)了 };
參數(shù)明確指定類(lèi)型的函數(shù)表達(dá)式將會(huì)忽略上下文歸類(lèi)。經(jīng)過(guò)這樣的處理就不會(huì)報(bào)錯(cuò)了,因?yàn)闆](méi)有應(yīng)用到上下文歸類(lèi)。
上下文歸類(lèi)可應(yīng)用于許多場(chǎng)景。常見(jiàn)的場(chǎng)景包括函數(shù)調(diào)用的參數(shù)、賦值的等號(hào)右邊表達(dá)式、類(lèi)型確定、對(duì)象成員和數(shù)組字面量、返回值語(yǔ)句。上下文類(lèi)型也作為最佳公共類(lèi)型的候選類(lèi)型。例如:
function createZoo(): Animal[] { return [new Rhino(), new Elephant(), new Snake()]; }
在這個(gè)例子中,最佳公共類(lèi)型有四個(gè)候選類(lèi)型:Animal,Rhino,Elephant,和Snake。其中,Animal可以作為最佳公共類(lèi)型。
形式有點(diǎn)像數(shù)學(xué)中的求最小公倍數(shù)...
相關(guān)文章
深入理解Javascript中的循環(huán)優(yōu)化
這篇文章介紹了Javascript中的循環(huán)優(yōu)化,有需要的朋友可以參考一下2013-11-11基于casperjs和resemble.js實(shí)現(xiàn)一個(gè)像素對(duì)比服務(wù)詳解
這篇文章主要給大家介紹了關(guān)于基于casperjs和resemble.js實(shí)現(xiàn)一個(gè)像素對(duì)比服務(wù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01uniapp如何編寫(xiě)含有后端的登錄注冊(cè)頁(yè)面
uniapp是一個(gè)使用html5標(biāo)準(zhǔn)的,一次開(kāi)發(fā),可以發(fā)布到安卓,ios,小程序的多端框架,非常方便,下面這篇文章主要給大家介紹了關(guān)于uniapp如何編寫(xiě)含有后端的登錄注冊(cè)頁(yè)面的相關(guān)資料,需要的朋友可以參考下2023-05-05小程序開(kāi)發(fā)之uniapp引入iconfont圖標(biāo)以及使用方式
uniapp本身是有icon組件的,但由于icon組件各端表現(xiàn)存在差異,所以我們可以通過(guò)使用iconfont的字體圖標(biāo)來(lái)彌補(bǔ)這些差異,下面這篇文章主要給大家介紹了關(guān)于小程序開(kāi)發(fā)之uniapp引入iconfont圖標(biāo)以及使用方式的相關(guān)資料,需要的朋友可以參考下2022-11-11Bootstrap路徑導(dǎo)航與分頁(yè)學(xué)習(xí)使用
這篇文章主要為大家詳細(xì)介紹了Bootstrap路徑導(dǎo)航與分頁(yè)學(xué)習(xí)使用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02js獲取客戶端操作系統(tǒng)類(lèi)型的方法【測(cè)試可用】
這篇文章主要介紹了js獲取客戶端操作系統(tǒng)類(lèi)型的方法,可有效的判斷常見(jiàn)操作系統(tǒng)的類(lèi)型,包括Windows、MacOS、Unix及Linux等,涉及javascript頁(yè)面navigator.userAgent屬性操作技巧,需要的朋友可以參考下2016-05-05基于BootStrap Metronic開(kāi)發(fā)框架經(jīng)驗(yàn)小結(jié)【六】對(duì)話框及提示框的處理和優(yōu)化
這篇文章主要介紹了基于BootStrap Metronic開(kāi)發(fā)框架經(jīng)驗(yàn)小結(jié)【六】對(duì)話框及提示框的處理和優(yōu)化的相關(guān)知識(shí),主要對(duì)比說(shuō)明在Bootstrap開(kāi)發(fā)中用到的這些技術(shù)要點(diǎn),對(duì)此文感興趣的朋友一起學(xué)習(xí)吧2016-05-05微信小程序?qū)崿F(xiàn)自定義modal彈窗封裝的方法
這篇文章主要介紹了小程序自定義modal彈窗封裝實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2018-06-06