新聞中心
大家好,我是前端西瓜哥。今天來學(xué)習(xí) TS 中幾個比較特殊的類型:any、never、never、void。

朔城網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),朔城網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為朔城近1000家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的朔城做網(wǎng)站的公司定做!
any
any 表示 任意類型。
它是任意類型的父類,任意類型的值都可以賦予給 any 類型:
// 編譯不會報錯
let anything: any = '前端西瓜哥';
let flag: boolean = true;
anything = flag;
anything = { num: 2 };
它可以表示任何類型,并使用它們的語法,就像寫沒有類型的原生 JS 一樣。
// 編譯不會報錯
const a: any = 6;
a();
a.key1 = true;
any 相當(dāng)于拋棄了類型系統(tǒng),會讓代碼變得不可預(yù)測和難以維護,需要程序員小心維護,一有不慎會造成運行時的錯誤,所以盡量少用。
但在引入一些沒有提供類型的第三方純 JS 庫時,還是得將它們標(biāo)為 any,這個確實沒啥辦法。
除非你自己給第三方庫寫類型聲明,但太不現(xiàn)實,因為你不熟悉第三方庫的 API,且可能有很復(fù)雜的類型推導(dǎo)要實現(xiàn)。
any 的存在是為了兼容無類型的 JS。TS 作為 JS 的超集,用 any 開后門是不得不做的事情。
unknown
unknown 可以認為是 類型更安全的 any。
和 any 一樣,unknown 也是任何類型的子類型,所有類型都可以傳給 unknown,包括 any。
// 編譯不會報錯
let a: unknown = '前端西瓜哥';
let b: any;
a = b;
a = { num: 2 };
說 unknown 更安全,是因為 unknown 是不能進行任何操作的。如果要使用,需要用 as 來進行顯式的類型斷言。
declare const user: known;
// 報錯,unknown 不能被使用
user.toLowerCase();
// 開發(fā)者認為 user 是個字符串
// 使用 as 進行類型推斷才能使用
(user as string).toLowerCase();
或者我們可以用類型收窄(Type Narrowing);
declare const user: unknown;
if (typeof user === 'string') {
user.toLowerCase();
}
對于一些可疑的沒有類型的變量,如果你不希望它被不小心使用,此時就可以用 unknown。
總結(jié)就是:unknown 能看不能用,想用先類型斷言。
never
never 表示一個 無法被觀測的類型,被賦予了該類型的變量什么都不能做。
使用 never 的一些場景。
(1)一個無法走到 return 返回值的函數(shù),比如一定會拋出錯誤或死循環(huán):
// 這里的 never 表示無法執(zhí)行到函數(shù)返回它的返回值
function foo(): never {
throw new Error('something wrong!')
}
(2)TS 在判斷條件下會做類型的收窄,當(dāng)類型收縮到無類型可用,類型就變成了 never:
function getData(id: number | string) {
if (typeof id === 'string') {
// id 類型變成了 string
} else if (typeof id === 'number') {
// id 類型變成了 number
} else {
// id 類型變成了 never
}
}或者做了一種不可能為 true 的類型收窄:
if (typeof id === 'number' && typeof id === 'string') {
// id 不可能同時是 number 和 string
// 所以會變成 never
}或無法求出交集的交叉類型:
// ImpossibleType 會得到 never
type ImpossibleType = string & number;
(3)類型編程中,在做模式匹配時,如果匹配失敗,還是要返回一個類型的。為了表示失敗,返回一個 never 表示返回的類型是無法被使用的。
比如 TS 內(nèi)置的 Parameters 高級類型,會通過模式匹配提取函數(shù)的參數(shù)數(shù)組類型。如果無法匹配到參數(shù),會返回 never:
type Parametersany> = T extends (...args: infer P) => any ? P : never
(4)類型編程中,將一些類型丟棄。never 在聯(lián)合類型以及重映射的 key 中會被丟棄。
比如 TS 內(nèi)置的 Exclude 高級類型,會將聯(lián)合類型 T 中的不屬于 U 的 key 丟棄掉。
type Exclude= T extends U ? never : T
type T = Exclude<"a" | "b" | "c", "a">;
// T 的類型為 "b" | "c"
// 其實應(yīng)該是 never | "b" | "c",但 never 無意義,被丟掉了
void
void 用于表示一個 函數(shù)沒有返回值。
function sayHi(): void {
console.log('Hi!');
}當(dāng)然在實際 JS 運行時,還是會返回一個默認的 undefined 的。但 TS 給返回值設(shè)置為 void,語義更好些。
總結(jié)
any 是任意類型,具有所有類型的行為,可被執(zhí)行,可訪問屬性,超脫于類型系統(tǒng)之外。
unknown 則是類型更安全的 any,同樣可以將任何類型賦給它,但不能執(zhí)行任何操作,必須用類型斷言來顯示說明類型才能去執(zhí)行操作。
never 是無法觀測的類型,比如不會執(zhí)行完的函數(shù)的返回值,合并結(jié)果不存在的交叉類型。在類型編程中非?;钴S,常用于丟棄一些子類型。
void 就比較簡單,只是代表函數(shù)沒有返回值,沒有其他的場景了。
網(wǎng)頁標(biāo)題:TypeScript中的Any、Unknown、Never和Void
標(biāo)題路徑:http://fisionsoft.com.cn/article/dpospcc.html


咨詢
建站咨詢
