Typescript中的as、問號與感嘆號詳解
1、as關(guān)鍵字表示斷言
在Typescript中,表示斷言有兩種方式。一種是擴號表示法:
let someValue: any = "this is a string"; let strLength: number = (someValue).length;
另一種使用as關(guān)鍵字:
let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;
2、問號(?)用于屬性定義
問號表示可選的屬性,一般用于屬性定義,如,用于接口時:
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig) { if (config.color) { console.log(config); } }
可選屬性的含義是:使用這個屬性時,要么這個屬性名不存在,要么必須符合屬性的類型定義
比如上述createSquare函數(shù)編譯時會報error錯誤:
error TS2551: Property 'clor' does not exist on type 'SquareConfig'.
如果修改createSquare,將config.color的值改為undefined,會怎樣?
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig) { config.color = undefined; if (config.color) { console.log(config); } }
這時并沒有編譯報錯!明明config.color定義的是string類型呀?
即便是添加–strictNullChecks進行編譯,也不會報錯。可見,可選屬性所定義的類型,并沒有被typescript嚴(yán)格地對待,默認(rèn)并不檢查undefined。需要注意的是,將上述undefined改成null時,普通編譯也不報錯,–strictNullChecks編譯會報如下錯誤:
error TS2322: Type 'null' is not assignable to type 'string | undefined'
從這句報錯中,我們可以得出這樣的結(jié)論:可選屬性等價于一個union類型,union了undefined;不加–strictNullChecks編譯時,null可以賦值給undfined類型。也就是說,SquareConfig的定義與下面的代碼等價:
interface SquareConfig { color: string|undefined; width: number|undefined; }
下面比較一下可選屬性與正常屬性。再次修改createSquare,將color屬性修改為正常屬性。
interface SquareConfig { color: string; width?: number; } function createSquare(config: SquareConfig) { config.color = undefined; if (config.color) { console.log(config); } }
以–strictNullChecks編譯,報錯了:
error TS2322: Type ‘undefined' is not assignable to type ‘string'
這個比較也驗證了上述的結(jié)論。
問號(?)用于屬性讀取
問號用于屬性讀取,主要有兩個場景:一是讀取數(shù)組元素(如下面的node[i]),二是讀取不確定的類型如any,union,可選類型(如node[i].data)等。如下例,保存為index.ts:
interface VNodeData { class?: string; } interface VNode { sel?: string; data?: VNodeData; } function test(node: VNode[]) { let i = 0; var b = node[i].data.class; if(b !== undefined) { console.log(1); } }
用tsc --strictNullChecks index.ts,報錯:
error TS2532: Object is possibly 'undefined'
下面將一一展示這一行代碼var b = node[i].data.class;修改改后的效果。
1、修改為var b = node[i]?.data.class;,然后編譯。報錯:
Object is possibly 'undefined'
2、修改為var b = node[i]?.data?.class;,然后編譯。編譯通過,查看編譯后的對應(yīng)代碼為:
function test(node) { var _a, _b; var i = 0; var b = (_b = (_a = node[i]) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b["class"]; // var b = node[i].data.class;//報錯 if (b !== undefined) { console.log(1); } }
var b = node[i]?表示,如果node[i]的值為null或者undefined,則b等于undefined,否則b=node[i]。
3、修改為var b = (node[i] as VNode).data?.class;,然后編譯。編譯通過,查看編譯后的對應(yīng)代碼為:
function test(node) { var _a; var i = 0; var b = (_a = node[i].data) === null || _a === void 0 ? void 0 : _a["class"]; // var b = node[i]?.data?.class; // var b = node[i].data.class;//報錯 if (b !== undefined) { console.log(1); } }
此時,使用node[i]時,Typescript編譯器將不再對其判斷是否為null和undefined。即:var b = node[i] as VNode直接會被編成var b = node[i]。
4、修改為var b = node[i]!.data?.class,然后編譯。編譯通過,查看編譯后的對應(yīng)代碼為:
function test(node) { var _a; var i = 0; var b = (_a = node[i].data) === null || _a === void 0 ? void 0 : _a["class"]; // var b = (node[i] as VNode).data?.class // var b = node[i]?.data?.class; // var b = node[i].data.class;//報錯 if (b !== undefined) { console.log(1); } }
可見,3和4的編譯后代碼完全一樣,!的作用此時與as是等價的。然而,!只是用來判斷null和undefined;as則可用于變更(縮小或者放大都可以)類型檢測范圍,僅當(dāng)as后面跟的類型是一個非空類型時,兩者才等價。如下例中,不能將as用法改為!。
interface Cat { action: string; } interface Dog { action: string; } type Animal = Cat | Dog; let action:Animal = {} as Cat;
結(jié)論
1、as和!用于屬性的讀取,都可以縮小類型檢查范圍,都做判空用途時是等價的。只是!具體用于告知編譯器此值不可能為空值(null和undefined),而as不限于此。
2、?可用于屬性的定義和讀取,讀取時告訴編譯器此值可能為空值(null和undefined),需要做判斷。
到此這篇關(guān)于Typescript中的as、問號與感嘆號詳解的文章就介紹到這了,更多相關(guān)Typescript中as、問號與感嘆號內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS數(shù)組遍歷中for,for in,for of,map,forEach各自的使用方法與優(yōu)缺點
這篇文章主要介紹了JS數(shù)組遍歷中for,for in,for of,map,forEach各自的使用方法與優(yōu)缺點,需要的朋友可以參考下2022-01-01javascript中聲明函數(shù)的方法及調(diào)用函數(shù)的返回值
這篇文章主要介紹了javascript中聲明函數(shù)的方法及調(diào)用函數(shù)時的返回值,示例如下,不了解的方法可以參考下2014-07-07Javascript中arguments和arguments.callee的區(qū)別淺析
這篇文章主要介紹了Javascript中arguments和arguments.callee的區(qū)別淺析,本文用一個實例來理解它們的區(qū)別,需要的朋友可以參考下2015-04-04JavaScript數(shù)據(jù)結(jié)構(gòu)與算法之鏈表
鏈表就是線性表中針對順序存儲結(jié)構(gòu)的一種優(yōu)化手段,但是在javascript語言中由于數(shù)組的特殊性(自動更新引用位置),所以我們可以采用對象的方式做鏈表存儲的結(jié)構(gòu)2016-01-01JavaScript中Array 對象相關(guān)的幾個方法
JavaScript中Array 對象相關(guān)的幾個方法...2006-12-12