Typescript中的as、問(wèn)號(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、問(wèn)號(hào)(?)用于屬性定義
問(wèn)號(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í)并沒(méi)有編譯報(bào)錯(cuò)!明明config.color定義的是string類型呀?
即便是添加–strictNullChecks進(jìn)行編譯,也不會(huì)報(bào)錯(cuò)??梢?jiàn),可選屬性所定義的類型,并沒(méi)有被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類型。也就是說(shuō),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é)論。
問(wèn)號(hào)(?)用于屬性讀取
問(wèn)號(hào)用于屬性讀取,主要有兩個(gè)場(chǎng)景:一是讀取數(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;,然后編譯。編譯通過(guò),查看編譯后的對(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;,然后編譯。編譯通過(guò),查看編譯后的對(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,然后編譯。編譯通過(guò),查看編譯后的對(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);
}
}
可見(jiàn),3和4的編譯后代碼完全一樣,!的作用此時(shí)與as是等價(jià)的。然而,!只是用來(lái)判斷null和undefined;as則可用于變更(縮小或者放大都可以)類型檢測(cè)范圍,僅當(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、問(wèn)號(hào)與感嘆號(hào)詳解的文章就介紹到這了,更多相關(guān)Typescript中as、問(wèn)號(hào)與感嘆號(hào)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Javascript基礎(chǔ)知識(shí)(一)核心基礎(chǔ)語(yǔ)法與事件模型
這篇文章主要介紹了Javascript用途及語(yǔ)法,傳統(tǒng)事件及現(xiàn)代事件,是最近這段時(shí)間個(gè)人學(xué)習(xí)javascript的一些心得,分享給大家,有需要的朋友可以參考下2014-09-09
深入學(xué)習(xí)JavaScript中的Rest參數(shù)和參數(shù)默認(rèn)值
這篇文章主要介紹了深入學(xué)習(xí)JavaScript中的Rest參數(shù)和參數(shù)默認(rèn)值,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-07-07
JavaScript onkeypress事件入門(mén)實(shí)例(按下或按住一個(gè)鍵盤(pán)按鍵)
這篇文章主要介紹了JavaScript onkeypress事件入門(mén)實(shí)例,onkeypress事件捕捉按下或按住一個(gè)鍵盤(pán)按鍵的情況,需要的朋友可以參考下2014-10-10
javaScript事件機(jī)制兼容【詳細(xì)整理】
下面小編就為大家?guī)?lái)一篇javaScript事件機(jī)制兼容【詳細(xì)整理】。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
javascript驗(yàn)證form表單數(shù)據(jù)的案例詳解
這篇文章主要介紹了javascript驗(yàn)證form表單數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
在JavaScript中操作時(shí)間之getUTCDate()方法的使用
這篇文章主要介紹了在JavaScript中操作時(shí)間之getUTCDate()方法的使用,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06

