TypeScript 中 any、unknown、never 和 void 有什么區(qū)別?
回復(fù)交流,加入前端編程面試算法每日一題群

any、unknown、never、void
any
any 類型用于描述一個我們根本不知道類型的變量,或者說可以是任意類型的變量,不作任何約束,編譯時會跳過對其的類型檢查
let notSure: any
// 可以被賦值任意類型
notSure = 'sisterAn!'
notSure = 512
notSure = { hello: () => 'Hello sisterAn!' }
// 它也兼容任何類型
let num: number = 12
notSure = num
num = notSure
unknown
unknown 表示未知類型,即寫代碼的時候還不知道具體會是怎樣的數(shù)據(jù)類型,是 typescript 3.0 中引入的新類型, 與 any 類似,所有類型都可以分配給unknown 類型
let notSure: unknown = 'sisterAn!'
// 可以被賦值任意類型
notSure = 'sisterAn!'
notSure = 512
notSure = { hello: () => 'Hello sisterAn!' }
但與 any 不同的是, unknown 類型的變量不允許被 any 或 unknown 以外的變量賦值,也不允許執(zhí)行 unknown 類型變量的方法
let notSure: unknown = 'sisterAn'
let notSure1: unknown = 'Hello'
let any1: any = 12
let num: number = 12
notSure = notSure1
notSure = any1
num = notSure
// error: Type 'unknown' is not assignable to type 'number'.
notSure.toLowerCase()
// error: Object is of type 'unknown'.
這種限制有很強(qiáng)的防御性,但如果我們要對未知類型執(zhí)行某些操作,也不是沒有辦法
方式一:使用類型斷言縮小未知范圍
let notSure: unknown = 'sisterAn'
console.log((notSure as string).toLowerCase())
方式二:使用類型守衛(wèi)進(jìn)行類型收縮
let notSure: unknown = 'sisterAn'
if (typeof notSure === 'string') {
console.log((notSure as string).toLowerCase())
}
// 或使用 instanceof 來縮小變量的類型
我們僅在 notSure 為 string 類型時,才執(zhí)行 toLowerCase 方法,TypeScript 編譯器會理解這一點,并假設(shè)類型
never
never ,永不存在的值的類型,是 typescript 2.0 中引入的新類型,那什么是永不存在的類型,我們知道變量一旦聲明,都會默認(rèn)初始化為 undefined ,也不是永不存在的值,但其實有一些場景,值會永不存在,例如,那些總是會拋出異?;蚝瘮?shù)中執(zhí)行無限循環(huán)的代碼(死循環(huán))的函數(shù)返回值類型
// 拋出異常
function error(msg: string): never {
throw new Error(msg);
} // 拋出異常會直接中斷程序運行,這樣程序就運行不到返回值那一步了,即具有不可達(dá)的終點,也就永不存在返回了
// 死循環(huán)
function loopForever(): never {
while (true) {};
} //同樣程序永遠(yuǎn)無法運行到函數(shù)返回值那一步,即永不存在返回
變量也可以聲明為 never 類型,因為它是永不存在值的類型,所以任何類型都不能賦值給 never 類型(除了never本身之外)。即使 any 也不可以賦值給 never
let never1: never
// any 也不能分配給 never
let any1: any = 'sisterAn'
never1 = any1 // Error
// 作為函數(shù)返回類型的 never
let never2: never = (() => {
throw new Error('Throw error');
})();
never1 = never2
void
void 某種程度上來說正好與 any 相反,表示無任何類型,沒有類型,如果是函數(shù)則應(yīng)沒有返回值或者返回 undefined :
function hello(): void {
console.log("Hello sisterAn");
}
也可以聲明一個 void 類型的變量,不過你只能為它賦予 undefined 、 null (注意,"strictNullChecks": true 時會報錯)和 void 類型的值
let void1: void
let null1: null = null
let und1: undefined = undefined
let void2: void
void1 = void2
void1 = und1
void1 = null1 // Type 'null' is not assignable to type 'void'.
any、unknown、never、void 區(qū)別
1. 定義
any:用于描述任意類型的變量,不作任何約束,編譯時會跳過對其的類型檢查unknown:表示未知類型,即寫代碼的時候還不知道具體會是怎樣的數(shù)據(jù)類型never:永不存在的值的類型,常用于表示永不能執(zhí)行到終點的函數(shù)返回值,例如拋出異常或函數(shù)中執(zhí)行無限循環(huán)的代碼(死循環(huán))的函數(shù)返回值類型void:表示無任何類型,沒有類型,例如沒有返回值的函數(shù)的返回值類型
any 與 unknown 的區(qū)別:
unknown 與 any 類似,但使用前必須進(jìn)行斷言或守衛(wèi)
never 與 void 的區(qū)別:
用于函數(shù)時, never 表示函數(shù)用于執(zhí)行不到返回值那一步(拋出異常或死循環(huán))的返回值類型,即永不存在的值的類型,而 void 則表示沒有返回值,不返回或返回 undefined
2. 使用
any類型導(dǎo)致問題太多了,如類型污染,使用不存在的屬性或方法而不報錯等,而且不不方便后期維護(hù),所以,建議能不用any就不用any,但是如果聲明時并不確定具體的類型,則可以使用unknown代替,在使用時用類型斷言或類型守衛(wèi)進(jìn)行類型收縮never類型用于表示永不存在的值的類型,所以常用于構(gòu)造條件類型來組合出更靈活的類型定義
// never: 從未出現(xiàn)的值的類型
// 如果 T 是 U 的子類型的話,那么就會返回 X,否則返回 Y
// 構(gòu)造條件類型 : T extends U ? X : Y
type Exclude<T, U> = T extends U ? never : T;
// 相當(dāng)于: type A = 'a'
type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>
void常用于表示函數(shù)沒有返回值
參考鏈接
ts官網(wǎng)
TypeScript 中類型 any,void,unknown,never之間的區(qū)別
來源:https://github.com/Advanced-Frontend/Daily-Interview-Question
最后
號內(nèi)回復(fù):
120 套模版
