最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript特殊類型與空值安全詳解

 更新時(shí)間:2026年04月02日 10:11:12   作者:燭銜溟  
本文介紹了TypeScript中advanced types,包括any、unknown、void、never、null、undefined等類型,詳細(xì)講解了它們的設(shè)計(jì)初衷、使用場(chǎng)景及注意事項(xiàng),幫助開(kāi)發(fā)者更好地理解和使用這些類型,提高代碼的安全性和可讀性

本文獻(xiàn)給:

已掌握 TypeScript 基礎(chǔ)類型(string、number、boolean、數(shù)組、元組、枚舉)的開(kāi)發(fā)者。本文將帶你探索 TypeScript 中更特殊的類型,理解它們的設(shè)計(jì)初衷與使用場(chǎng)景,并掌握處理空值的安全技巧。

你將學(xué)到:

  1. any 的弊端與 unknown 的安全用法
  2. voidnever 的區(qū)別及適用場(chǎng)景
  3. nullundefinedstrictNullChecks 下的行為
  4. 可選鏈 ?. 與空值合并 ?? 的使用
  5. 非空斷言 ! 的風(fēng)險(xiǎn)與正確使用方式

一、any —— 危險(xiǎn)的逃生艙

1.1 什么是 any?

any 是 TypeScript 中的頂級(jí)類型,可以表示任意值。被標(biāo)記為 any 的變量會(huì)關(guān)閉所有類型檢查,相當(dāng)于回到了 JavaScript 的動(dòng)態(tài)類型。

let value: any = "hello";
value = 42;           // OK
value = true;         // OK
value.toUpperCase();  // OK(運(yùn)行時(shí)可能出錯(cuò))

1.2 any 的弊端

any 雖然靈活,但會(huì)破壞 TypeScript 的類型安全保障:

let data: any = { name: "Alice" };
console.log(data.age.toFixed());  // ? 編譯通過(guò),運(yùn)行時(shí)報(bào)錯(cuò)(Cannot read property 'toFixed' of undefined)

any 還會(huì)污染其他類型,因?yàn)槿魏钨x值都會(huì)導(dǎo)致接收方也變成 any 或失去精確類型:

let dangerous: any = "text";
let safe: number = dangerous;   // 不報(bào)錯(cuò),但 safe 實(shí)際是 string,后續(xù)使用可能出問(wèn)題

1.3 何時(shí)可以容忍 any?

  • 快速原型開(kāi)發(fā)或遷移舊代碼時(shí)臨時(shí)使用
  • 第三方庫(kù)沒(méi)有類型定義且無(wú)法立即補(bǔ)全時(shí)
  • 某些極其復(fù)雜的動(dòng)態(tài)場(chǎng)景,類型難以表達(dá)

盡量用 unknown 替代 any,保持類型安全。

二、unknown —— 安全的 any

2.1 unknown 的特性

unknown 是 TypeScript 3.0 引入的安全類型,表示“不知道是什么類型”。與 any 不同,unknown 的值不能直接使用,必須經(jīng)過(guò)類型收窄(narrowing)后才能操作。

let value: unknown = "hello";
value = 42;           // OK
value = true;         // OK

// 直接使用會(huì)報(bào)錯(cuò)
value.toUpperCase();  // ? 類型 unknown 沒(méi)有 toUpperCase 方法

// 必須先收窄類型
if (typeof value === "string") {
    console.log(value.toUpperCase());  // OK
}

2.2 unknown 的使用場(chǎng)景

  • any 遷移時(shí),先用 unknown 替代,強(qiáng)制后續(xù)收窄
  • 處理 API 響應(yīng)、用戶輸入等不確定來(lái)源的數(shù)據(jù)
  • 編寫通用工具函數(shù),要求使用者顯式處理類型
function safeParse(input: string): unknown {
    return JSON.parse(input);
}

const result = safeParse('{"name":"Alice"}');
// 不能直接訪問(wèn) result.name,需要收窄
if (typeof result === "object" && result !== null && "name" in result) {
    console.log(result.name);  // OK
}

2.3 unknown 與 any 對(duì)比

特性anyunknown
可賦值給任何類型??(需先收窄)
可調(diào)用方法或?qū)傩?/td>?(編譯通過(guò))?(編譯報(bào)錯(cuò))
安全性低(繞過(guò)類型檢查)高(強(qiáng)制類型收窄)
適用場(chǎng)景快速原型、遺留代碼類型未知但需安全處理

三、void 與 never —— 函數(shù)的“無(wú)返回值”

3.1 void —— 沒(méi)有返回值的函數(shù)

void 表示一個(gè)函數(shù)沒(méi)有返回值,或者返回 undefined(在嚴(yán)格模式下)。

function logMessage(msg: string): void {
    console.log(msg);
    // 沒(méi)有 return,或 return; 或 return undefined;
}

變量也可以聲明為 void,但只能賦值為 undefinednull(非嚴(yán)格模式):

let unusable: void = undefined;
unusable = null;  // 僅在 strictNullChecks: false 時(shí)允許

注意:在回調(diào)函數(shù)中,如果期望函數(shù)不返回值,應(yīng)標(biāo)注 void,而不是 undefined(因?yàn)?undefined 表示必須返回 undefined)。

3.2 never —— 永遠(yuǎn)不會(huì)返回的函數(shù)

never 表示永遠(yuǎn)不會(huì)正常結(jié)束的函數(shù),例如:

  • 拋出異常(函數(shù)執(zhí)行被中斷)
  • 無(wú)限循環(huán)
function throwError(message: string): never {
    throw new Error(message);
}

function infiniteLoop(): never {
    while (true) {}
}

never 是所有類型的子類型,可以賦值給任何類型;但沒(méi)有類型是 never 的子類型(除了 never 自身)。

3.3 void 與 never 的區(qū)別

特性voidnever
含義函數(shù)正常結(jié)束,無(wú)返回值函數(shù)永遠(yuǎn)不會(huì)正常結(jié)束
可賦值的值undefined 或 null無(wú)(無(wú)法正常返回)
使用場(chǎng)景無(wú)返回值的函數(shù)(如事件處理)異常拋出、無(wú)限循環(huán)、類型守衛(wèi)的窮盡檢查

never 在類型守衛(wèi)中的妙用

switch 或條件判斷中,可以用 never窮盡檢查

type Shape = "circle" | "square";

function area(shape: Shape) {
    switch (shape) {
        case "circle":
            return Math.PI * 1 ** 2;
        case "square":
            return 1 * 1;
        default:
            const _exhaustiveCheck: never = shape;  // 如果 shape 類型被擴(kuò)展,這里會(huì)報(bào)錯(cuò)
            return _exhaustiveCheck;
    }
}

四、null 與 undefined —— 空值處理

4.1 嚴(yán)格空值檢查(strictNullChecks)

TypeScript 的 strictNullChecks 選項(xiàng)(默認(rèn)開(kāi)啟)嚴(yán)格區(qū)分 nullundefined 和其他類型。

  • 開(kāi)啟后,nullundefined 只能賦值給 anyunknown 或它們自身的類型。
  • 變量聲明時(shí)如果不包含 null/undefined,則不能賦值為這些空值。
// strictNullChecks: true
let name: string = "Alice";
name = null;      // ? 不能將 null 賦給 string
name = undefined; // ?

let age: number | null = 30;
age = null;       // OK

4.2 聯(lián)合類型與空值

常見(jiàn)模式是用聯(lián)合類型允許 nullundefined

let maybeName: string | null = "Alice";
maybeName = null;   // OK

let maybeAge: number | undefined = 25;
maybeAge = undefined; // OK

4.3 可選鏈(Optional Chaining)?.

訪問(wèn)深層屬性時(shí),如果中間某個(gè)屬性可能為 nullundefined,使用 ?. 可以安全地短路返回 undefined。

interface User {
    address?: {
        city?: string;
    };
}

let user: User = {};

// 傳統(tǒng)方式
let city = user.address && user.address.city;  // undefined

// 可選鏈
let city2 = user.address?.city;  // undefined

可選鏈也支持函數(shù)調(diào)用和數(shù)組索引:

let result = obj.method?.();   // 如果 method 不存在,返回 undefined
let item = arr?.[0];           // 如果 arr 是 null/undefined,返回 undefined

4.4 空值合并(Nullish Coalescing)??

?? 運(yùn)算符用于在左側(cè)值為 nullundefined 時(shí)返回右側(cè)值,與 || 不同,它不會(huì)將 0、""、false 視為假值。

let value1 = null ?? "default";   // "default"
let value2 = undefined ?? "default"; // "default"
let value3 = 0 ?? "default";      // 0(不是 null/undefined,保留原值)
let value4 = "" ?? "default";     // ""(同上)

// 對(duì)比 ||
let value5 = 0 || "default";      // "default"(|| 會(huì)將 0 視為假值)

4.5 非空斷言(Non-null Assertion)!

當(dāng) TypeScript 無(wú)法確定一個(gè)值不為 nullundefined,但開(kāi)發(fā)者確信它一定存在時(shí),可以使用 ! 后綴斷言。

let element = document.getElementById("app")!;  // 斷言該元素一定存在
element.innerHTML = "Hello";

// 也可以用于屬性訪問(wèn)
interface User {
    name?: string;
}
let user: User = { name: "Alice" };
let name = user.name!.toUpperCase();  // 斷言 name 存在

風(fēng)險(xiǎn)

! 只是編譯時(shí)斷言,不會(huì)生成運(yùn)行時(shí)檢查。如果斷言錯(cuò)誤,運(yùn)行時(shí)仍可能拋出 Cannot read property of undefined。應(yīng)謹(jǐn)慎使用,優(yōu)先考慮可選鏈或類型守衛(wèi)。

4.6 空值處理最佳實(shí)踐

場(chǎng)景推薦方式
訪問(wèn)可能不存在的深層屬性可選鏈 ?.
為 null/undefined 提供默認(rèn)值空值合并 ??
確信某個(gè)值非空但 TypeScript 不認(rèn)可先用 ?. 或類型守衛(wèi),最后才考慮 !
函數(shù)參數(shù)或返回值允許空值顯式使用聯(lián)合類型 string | null
類型守衛(wèi)收窄if (value !== null) { ... } 或 typeof

五、常見(jiàn)錯(cuò)誤與注意事項(xiàng)

5.1 誤用 any 導(dǎo)致類型失效

let data: any = fetchData();
let result = data.user.name;  // 無(wú)報(bào)錯(cuò),但可能運(yùn)行時(shí)崩潰

解決:用 unknown + 類型守衛(wèi)。

5.2 將 void 與 undefined 混用

function fn(): void {
    return undefined;  // OK
}
function fn2(): void {
    return null;       // ? 嚴(yán)格模式下不能返回 null
}

5.3 非空斷言濫用

let maybeNum: number | null = Math.random() > 0.5 ? 42 : null;
let definitelyNum = maybeNum!;  // 如果為 null,運(yùn)行時(shí)錯(cuò)誤

解決:使用 if (maybeNum !== null)??。

5.4 可選鏈與空值合并的混用陷阱

let val = obj?.prop ?? "default";
// 如果 obj 不存在,obj?.prop 返回 undefined,觸發(fā) ??
// 如果 obj.prop 存在但值為 null,也會(huì)觸發(fā) ??

六、綜合示例

// 模擬 API 響應(yīng)
interface ApiResponse<T> {
    data?: T;
    error?: string;
}

// 處理不確定的響應(yīng)
async function fetchUser(): Promise<ApiResponse<{ name: string }>> {
    // 模擬隨機(jī)成功或失敗
    const success = Math.random() > 0.5;
    if (success) {
        return { data: { name: "Alice" } };
    } else {
        return { error: "Network error" };
    }
}

async function handleUser() {
    const response = await fetchUser();
    
    // 使用 unknown 安全處理
    const unknownData: unknown = response.data;
    
    // 類型收窄
    if (unknownData && typeof unknownData === "object" && "name" in unknownData) {
        console.log(unknownData.name);  // 類型推斷為 string
    } else {
        console.log(response.error ?? "Unknown error");
    }
    
    // 可選鏈與空值合并示例
    const userName = response.data?.name ?? "Guest";
    console.log(`User: ${userName}`);
}

// never 示例:類型守衛(wèi)窮盡檢查
type Status = "pending" | "success" | "error";

function getStatusMessage(status: Status): string {
    switch (status) {
        case "pending":
            return "Loading...";
        case "success":
            return "Success!";
        case "error":
            return "Failed.";
        default:
            const _exhaustive: never = status;  // 如果 Status 增加新值,這里會(huì)報(bào)錯(cuò)
            return _exhaustive;
    }
}

七、小結(jié)

類型含義使用場(chǎng)景
any任意類型,關(guān)閉檢查臨時(shí)逃生艙,盡量少用
unknown未知類型,強(qiáng)制收窄處理不確定數(shù)據(jù),更安全
void無(wú)返回值無(wú)返回值的函數(shù)
never永不返回異常、無(wú)限循環(huán)、窮盡檢查
null空值明確表示“沒(méi)有值”
undefined未定義未初始化的變量、缺失屬性
?.可選鏈安全訪問(wèn)深層屬性
??空值合并為 null/undefined 提供默認(rèn)值
!非空斷言確信值非空時(shí)使用,需謹(jǐn)慎

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

贵州省| 乃东县| 策勒县| 韶关市| 扎赉特旗| 新绛县| 特克斯县| 巴林左旗| 永川市| 临桂县| 广宁县| 莱阳市| 萍乡市| 沙雅县| 福鼎市| 灵台县| 金乡县| 安庆市| 工布江达县| 南城县| 东城区| 万载县| 古浪县| 神池县| 灵璧县| 博爱县| 纳雍县| 天峻县| 高雄市| 锡林郭勒盟| 靖远县| 土默特左旗| 理塘县| 牙克石市| 阳西县| 通道| 绿春县| 磐安县| 衡水市| 武强县| 甘洛县|