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