日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
TypeScript 你還只會(huì)用 Any?

在 TypeScript 中,any 類型被稱為 top type。所謂的 top type 可以理解為通用父類型,也就是能夠包含所有值的類型。

濮陽(yáng)網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),濮陽(yáng)網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為濮陽(yáng)上1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的濮陽(yáng)做網(wǎng)站的公司定做!

let value: any;

value = true; // OK
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
value = Math.random; // OK
value = null; // OK
value = undefined; // OK
value = new TypeError(); // OK
value = Symbol("type"); // OK

而在 TypeScript 3.0 時(shí),又引入一個(gè)新的 top type —— unknown 類型。同樣,你也可以把任何值賦給 unknown 類型的變量。

let value: unknown;

value = true; // OK
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
value = Math.random; // OK
value = null; // OK
value = undefined; // OK
value = new TypeError(); // OK
value = Symbol("type"); // OK

那么現(xiàn)在問題來(lái)了,any 類型和 unknown 類型之間有什么區(qū)別呢?any 類型可以理解成我不在乎它的類型,而 unknown 類型可以理解成我不知道它的類型。

其實(shí) any 類型本質(zhì)上是類型系統(tǒng)的一個(gè)逃生艙口,TypeScript 允許我們對(duì) any 類型的值執(zhí)行任何操作,而無(wú)需事先執(zhí)行任何形式的檢查。

let value: any;

value.foo.bar; // OK
value.trim(); // OK
value(); // OK
new value(); // OK
value[0][1]; // OK

這會(huì)帶來(lái)什么問題呢?下面我們來(lái)舉一個(gè)例子:

function invokeCallback(callback: any) {
try {
callback();
} catch (err) {
console.error(err)
}
}

invokeCallback(1);

對(duì)于以上的 TS 代碼,在編譯期不會(huì)提示任何錯(cuò)誤,但在運(yùn)行期將會(huì)拋出運(yùn)行時(shí)錯(cuò)誤。作為開發(fā)人員,any 類型給了我們很大的自由度,但同時(shí)也帶來(lái)了一些隱患。

為了解決 any 類型存在的安全隱患,TypeScript 團(tuán)隊(duì)在 3.0 版本時(shí),引入了 unknown 類型,你可以把它理解成類型安全的 any 類型。

那么 unknown 類型是類型安全的體現(xiàn)在哪里呢?這里我們把 invokeCallback 函數(shù)參數(shù)的類型改為 unknown 類型,之后 TS 編譯器就會(huì)提示相應(yīng)的錯(cuò)誤信息:

function invokeCallback(callback: unknown) {
try {
// Object is of type 'unknown'.(2571)
callback(); // Error
} catch (err) {
console.error(err)
}
}

invokeCallback(1);

相比 any 類型,TypeScript 會(huì)對(duì) unknown 類型的變量執(zhí)行類型檢查,從而避免出現(xiàn) callback 參數(shù)非函數(shù)類型。要解決上述問題,我們需要縮小 callback 參數(shù)的類型,即可以通過 typeof 操作符來(lái)確保傳入的 callback 參數(shù)是函數(shù)類型的對(duì)象:

function invokeCallback(callback: unknown) {
try {
if (typeof callback === 'function') {
callback();
}
} catch (err) {
console.error(err)
}
}

invokeCallback(1);

在實(shí)際工作中,你還可以通過 instanceof 或用戶自定義類型守衛(wèi)等方式來(lái)縮窄變量的類型。

declare function isFunction(x: unknown): x is Function;

function f20(x: unknown) {
if (x instanceof Error) {
x; // Error
}
if (isFunction(x)) {
x; // Function
}
}

與 any 類型不同,因?yàn)?TypeScript 會(huì)對(duì) unknown 類型的變量執(zhí)行類型檢查,所以當(dāng)我們把之前代碼中 value 變量的類型改成 unknown 類型時(shí),使用 value 變量的多個(gè)語(yǔ)句將出現(xiàn)錯(cuò)誤。

let value: unknown;

// Object is of type 'unknown'.(2571)
value.foo.bar; // Error
value.trim(); // Error
value(); // Error
new value(); // Error
value[0][1]; // Error

另外,需要注意的是,unknown 類型的變量只能賦值給 any 類型和 unknown 類型本身。

let value: unknown;

let value1: unknown = value; // OK
let value2: any = value; // OK
let value3: boolean = value; // Error
let value4: number = value; // Error
let value5: string = value; // Error
let value6: object = value; // Error
let value7: any[] = value; // Error
let value8: Function = value; // Error

any 類型和 unknown 類型在這些場(chǎng)合中的表現(xiàn)也是不一樣的:

type T40 = keyof any;  // string | number | symbol
type T41 = keyof unknown; // never

type T50 = { [P in keyof T]: number };
type T51 = T50; // { [x: string]: number }
type T52 = T50; // {}

在以上代碼中,T50 類型被稱為映射類型,在映射過程中,如果 key 的類型是 never 類型,則當(dāng)前 key 將會(huì)被過濾掉,所以 T52 的類型是空對(duì)象類型。

關(guān)于 any 類型和 unknown 類型的區(qū)別就介紹到這里,現(xiàn)在我們來(lái)做個(gè)總結(jié):

  • 你可以把任何值賦給 any 類型的變量,并對(duì)該變量執(zhí)行任何操作;
  • 你可以把任何值賦給 unknown 類型的變量,但你必須進(jìn)行類型檢查或類型斷言才能對(duì)變量進(jìn)行操作;

在平時(shí)工作中,為了保證類型安全,我們應(yīng)該盡可能使用 unknown 類型。最后我們來(lái)看一下 unknown 類型與不同類型進(jìn)行類型運(yùn)算的結(jié)果:

// In an intersection everything absorbs unknown
type T00 = unknown & null; // null
type T01 = unknown & undefined; // undefined
type T02 = unknown & null & undefined; // null & undefined (which becomes never in union)
type T03 = unknown & string; // string
type T04 = unknown & string[]; // string[]
type T05 = unknown & unknown; // unknown
type T06 = unknown & any; // any

// In a union an unknown absorbs everything
type T10 = unknown | null; // unknown
type T11 = unknown | undefined; // unknown
type T12 = unknown | null | undefined; // unknown
type T13 = unknown | string; // unknown
type T14 = unknown | string[]; // unknown
type T15 = unknown | unknown; // unknown
type T16 = unknown | any; // any

any 類型比較特殊,該類型與任意類型進(jìn)行交叉或聯(lián)合運(yùn)算時(shí),都會(huì)返回 any 類型。

閱讀完本文之后,相信你已經(jīng)了解 any 類型和 unknown 類型之間的區(qū)別了。你知道如何檢測(cè) any 類型和 unknown 類型么?


本文題目:TypeScript 你還只會(huì)用 Any?
分享網(wǎng)址:http://www.dlmjj.cn/article/cdhhsgc.html