TypeScript中null和undefined的深入解析

在TypeScript中,nullundefined是两种特殊的类型,它们分别可以取nullundefined值。这两种类型不仅可以单独使用,还可以与其他类型组合成联合类型(Union Type),并且在类型守卫(Type Guards)中也有广泛应用。本文将通过实例深入探讨nullundefined在TypeScript中的使用方式及其在严格空值检查(--strictNullChecks)下的行为。

1. 基本用法

nullundefined可以作为联合类型的一部分,允许函数参数接受多种类型的值。例如:

function show(x: number | null | undefined) {
    if (x === undefined) {
        console.log("value not set");
    } else if (x === null) {
        console.log("value is null");
    } else {
        console.log(x);
    }
}

let x = 10;
let y;
let z = null;

show(x); // 输出: 10
show(y); // 输出: value not set
show(z); // 输出: value is null

在这个例子中,show函数的参数x可以接受numbernullundefined。通过简单的类型检查,我们可以区分输入值的类型并输出相应的结果。

2. 简化联合类型

在某些情况下,我们可以简化联合类型。例如,number | null也可以接受undefined值,因为TypeScript会自动将undefined视为可选值:

function show(x: number | null) {
    if (x === undefined) {
        console.log("value not set");
    } else if (x === null) {
        console.log("value is null");
    } else {
        console.log(x);
    }
}

let x = 10;
let y;
let z = null;

show(x); // 输出: 10
show(y); // 输出: value not set
show(z); // 输出: value is null

然而,如果仅使用number类型,TypeScript会阻止将nullundefined传递给函数:

function show(x: number) {
    if (x === undefined) {
        console.log("value not set");
    } else if (x === null) {
        console.log("value is null");
    } else {
        console.log(x);
    }
}

let x = 10;
let y;
let z = null;

show(x); // 输出: 10
show(y); // 报错:TS2345: Argument of type 'undefined' is not assignable to parameter of type 'number'.
show(z); // 报错:TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.

3. 严格空值检查(--strictNullChecks

当启用--strictNullChecks标志时,TypeScript会对nullundefined的使用进行更严格的检查。例如:

function show(x: number) {
    if (x === undefined) {
        console.log("value not set");
    } else if (x === null) {
        console.log("value is null");
    } else {
        console.log(x);
    }
}

let x = 10;
let y;
let z = null;

show(x); // 输出: 10
show(y); // 报错:TS2345: Argument of type 'undefined' is not assignable to parameter of type 'number'.
show(z); // 报错:TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.

在这种情况下,nullundefined不能被传递给number类型的参数,除非明确声明联合类型。

4. 可选参数与--strictNullChecks

可选参数(?)在默认情况下允许undefined值,但在启用--strictNullChecks时,行为会有所不同:

function show(x?: number) {
    if (x === undefined) {
        console.log("value not set");
    } else if (x === null) {
        console.log("value is null");
    } else {
        console.log(x);
    }
}

let x = 10;
let y;
let z = null;

show(x); // 输出: 10
show(y); // 输出: value not set
show(z); // 输出: value is null

启用--strictNullChecks后:

function show(x?: number) {
    if (x === undefined) {
        console.log("value not set");
    } else if (x === null) {
        console.log("value is null");
    } else {
        console.log(x);
    }
}

let x = 10;
let y;
let z = null;

show(x); // 输出: 10
show(y); // 输出: value not set
show(z); // 报错:TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'.

5. 总结

在TypeScript中,T | null | undefinedT | nullT在默认情况下是等价的,但启用--strictNullChecks后,nullundefined的使用会受到更严格的限制。具体来说:

  • T | null | undefinedT | null在默认情况下可以接受undefined值。
  • T类型不能接受nullundefined,除非明确声明联合类型。
  • 可选参数(?)在默认情况下允许undefined值,但在--strictNullChecks下,null值需要明确声明。

通过合理使用nullundefined,并结合--strictNullChecks标志,可以有效提升代码的安全性和可维护性。

示例项目

  • 依赖与技术
    • TypeScript 3.1.3