any 類型
基本含義
any 類型表示沒有任何限制,該類型的變量可以賦予任意類型的值聋呢。
let x:any;
x = 1; // 正確
x = 'foo'; // 正確
x = true; // 正確
上面示例中苗踪,變量x
的類型是any
,就可以被賦值為任意類型的值削锰。
變量類型一旦設(shè)為any
通铲,TypeScript 實(shí)際上會(huì)關(guān)閉這個(gè)變量的類型檢查。即使有明顯的類型錯(cuò)誤器贩,只要句法正確颅夺,都不會(huì)報(bào)錯(cuò)。
let x:any = 'hello';
x(1) // 不報(bào)錯(cuò)
x.foo = 100; // 不報(bào)錯(cuò)
上面示例中蛹稍,變量x
的值是一個(gè)字符串吧黄,但是把它當(dāng)作函數(shù)調(diào)用,或者當(dāng)作對(duì)象讀取任意屬性唆姐,TypeScript 編譯時(shí)都不報(bào)錯(cuò)拗慨。原因就是x
的類型是any
,TypeScript 不對(duì)其進(jìn)行類型檢查。
由于這個(gè)原因赵抢,應(yīng)該盡量避免使用any
類型剧蹂,否則就失去了使用 TypeScript 的意義。
實(shí)際開發(fā)中昌讲,any
類型主要適用以下兩個(gè)場(chǎng)合国夜。
(1)出于特殊原因,需要關(guān)閉某些變量的類型檢查短绸,就可以把該變量的類型設(shè)為any
车吹。
(2)為了適配以前老的 JavaScript 項(xiàng)目,讓代碼快速遷移到 TypeScript醋闭,可以把變量類型設(shè)為any
窄驹。有些年代很久的大型 JavaScript 項(xiàng)目,尤其是別人的代碼证逻,很難為每一行適配正確的類型乐埠,這時(shí)你為那些類型復(fù)雜的變量加上any
,TypeScript 編譯時(shí)就不會(huì)報(bào)錯(cuò)囚企。
總之丈咐,TypeScript 認(rèn)為,只要開發(fā)者使用了any
類型龙宏,就表示開發(fā)者想要自己來處理這些代碼棵逊,所以就不對(duì)any
類型進(jìn)行任何限制,怎么使用都可以银酗。
從集合論的角度看辆影,any
類型可以看成是所有其他類型的全集,包含了一切可能的類型黍特。TypeScript 將這種類型稱為“頂層類型”(top type)蛙讥,意為涵蓋了所有下層。
類型推斷問題
對(duì)于開發(fā)者沒有指定類型灭衷、TypeScript 必須自己推斷類型的那些變量次慢,如果無法推斷出類型,TypeScript 就會(huì)認(rèn)為該變量的類型是any
今布。
function add(x, y) {
return x + y;
}
add(1, [1, 2, 3]) // 不報(bào)錯(cuò)
上面示例中经备,函數(shù)add()
的參數(shù)變量x
和y
,都沒有足夠的信息部默,TypeScript 無法推斷出它們的類型侵蒙,就會(huì)認(rèn)為這兩個(gè)變量和函數(shù)返回值的類型都是any
。以至于后面就不再對(duì)函數(shù)add()
進(jìn)行類型檢查了傅蹂,怎么用都可以纷闺。
這顯然是很糟糕的情況算凿,所以對(duì)于那些類型不明顯的變量,一定要顯式聲明類型犁功,防止被推斷為any
氓轰。
TypeScript 提供了一個(gè)編譯選項(xiàng)noImplicitAny
,打開該選項(xiàng)浸卦,只要推斷出any
類型就會(huì)報(bào)錯(cuò)署鸡。
$ tsc --noImplicitAny app.ts
上面命令使用了noImplicitAny
編譯選項(xiàng)進(jìn)行編譯,這時(shí)上面的函數(shù)add()
就會(huì)報(bào)錯(cuò)限嫌。
污染問題
any
類型除了關(guān)閉類型檢查靴庆,還有一個(gè)很大的問題,就是它會(huì)“污染”其他變量怒医。它可以賦值給其他任何類型的變量(因?yàn)闆]有類型檢查)炉抒,導(dǎo)致其他變量出錯(cuò)。