TypeScript Nullable

TypeScript中的Nullable类型指的是值可以为undefinednull的类型。

JavaScript中有两个比较特殊的原始类型,即Undefined类型和Null类型。两者分别仅包含一个原始值,即undefined值和null值,它们通常用来表示某个值还未进行初始化。

在TypeScript早期的版本中,没有提供与JavaScript中Undefined类型和Null类型相对应的类型。TypeScript允许将undefined值和null值赋值给任何其他类型。虽然在TypeScript语言的内部实现中确实存在这两种原始类型,但是之前没有将它们开放给开发者使用。

TypeScript 2.0版本的一个改变就是增加了undefined类型和null类型供开发者使用。虽然看上去是一项普通的改进,但却有着非凡的意义。因为,不当地使用undefined值和null值是程序缺陷的主要来源之一,并有可能导致价值亿万美元的错误。相信一定有不少朋友都曾经遇到过如下的JavaScript程序错误:

TypeError: Cannot read property 'xxx' of undefined

现在,在TypeScript程序中能够明确地指定某个值的类型是否为undefined类型或null类型。TypeScript编译器也能够对代码进行更加细致的检查以找出程序中潜在的错误。

undefined

undefined类型只包含一个可能值,即undefined值。undefined类型使用undefined关键字标识。示例如下:

const foo: undefined = undefined;

null

null类型只包含一个可能值,即null值。null类型使用null关键字标识。示例如下:

const foo: null = null;

–strictNullChecks

TypeScript 2.0还增加了一个新的编译选项“--strictNullChecks”,即严格的null检查模式。虽然该编译选项的名字中只提及了null,但实际上它同时作用于undefined类型和null类型的类型检查。

在默认情况下,“--strictNullChecks”编译选项没有被启用。这时候,除尾端类型外的所有类型都是Nullable类型。也就是说,除尾端类型外所有类型都能够接受undefined值和null值。

例如,在没有启用“–strictNullChecks”编译选项时,允许将undefined值和null值赋值给string类型等其他类型。示例如下:

/**
* --strictNullChecks=false
*/
let m1: boolean   = undefined;
let m2: string    = undefined;
let m3: number    = undefined;
let m4: bigint    = undefined;
let m5: symbol    = undefined;
let m6: undefined = undefined;
let m7: null      = undefined;

let n1: boolean   = null;
let n2: string    = null;
let n3: number    = null;
let n4: bigint    = null;
let n5: symbol    = null;
let n6: undefined = null;
let n7: null      = null;

该模式存在一个明显的问题,就是无法检查出空引用的错误。

例如,已知某一个变量的类型是string,于是通过访问其length属性来获取该变量表示的字符串的长度。但如果string类型的变量值可以为undefined或null,那么这段代码在运行时将产生错误。示例如下:

/**
* --strictNullChecks=false
*/
let foo: string = undefined; // 正确,可以通过类型检查

foo.length;                  // 在运行时,将产生类型错误

运行结果:

TypeScript Nullable

此例中,将undefined值赋值给string类型的变量foo时不会产生编译错误。但是,在运行时尝试读取undefined值的length属性将产生类型错误。这个问题可以通过启用“–strictNullChecks”编译选项来避免。

当启用了“–strictNullChecks”编译选项时,undefined值和null值不再能够赋值给不相关的类型。例如,undefined值和null值不允许赋值给string类型。在该模式下,undefined值只能够赋值给undefined类型;同理,null值也只能赋值给null类型。

还是以上例中的代码为例,如果我们启用了“–strictNullChecks”编译选项,那么TypeScript编译器就能够检查出代码中的错误。示例如下:

/**
* --strictNullChecks=true
*/
let foo: string = undefined;
//  ~~~
//  编译错误!类型 'undefined' 不能赋值给类型 'string'
foo.length;

TypeScript在执行静态类型检查时就能够发现这处类型错误,从而避免了在代码运行时才发现这个缺陷。

前面我们说在启用了“–strictNullChecks”编译选项时,undefined值只能够赋值给undefined类型,null值只能够赋值给null类型,实际上这种表述不完全准确。因为在该模式下,undefined值和null值允许赋值给顶端类型,同时undefined值也允许赋值给void类型。

示例如下:

/**
* --strictNullChecks=true
*/
let m1: void = undefined;

let m2: any     = undefined;
let m3: unknown = undefined;

let n2: any     = null;
let n3: unknown = null;

undefined类型和null类型是不同的类型,它们必须被区分对待,不能互换使用。示例如下:

/**
* --strictNullChecks=true
*/
const foo: undefined = null;
//    ~~~
//    编译错误!类型 'null' 不能赋值给类型 'undefined'

const bar: null = undefined;
//    ~~~
//    编译错误!类型 'undefined' 不能赋值给类型 'null'

在了解了“–strictNullChecks”编译选项的作用后,让我们来看一看如何启用该编译选项。在默认情况下,“--strictNullChecks”编译选项没有被启用,我们需要在工程下的tsconfig.json配置文件中启用该编译选项,通过将“strictNullChecks”属性设置为“true”就能够启用“–strictNullChecks”编译选项。同理,如果将该属性设置为“false”则会关闭该编译选项。

示例如下:

{
   "compilerOptions": {
       "strictNullChecks": true
   }
}

酷客网相关文章:

赞(1)

评论 抢沙发

评论前必须登录!