TypeScript开启严格空值检查

举报
搞前端的半夏 发表于 2022/03/06 23:32:29 2022/03/06
【摘要】 个人博客: 搞前端的半夏欢迎关注公众号「搞前端的半夏」在TS中,有对应JS中的基础类型null和undefined。TypeScript里,JS中的基本数据类型undefined和null两者各自有自己的类型分别叫做undefined和null。let u: undefined = undefined;let n: null = null;默认情况下null和undefined是所有类型的子...

个人博客: 搞前端的半夏
欢迎关注公众号「搞前端的半夏」

在TS中,有对应JS中的基础类型null和undefined。

TypeScript里,JS中的基本数据类型undefinednull两者各自有自己的类型分别叫做undefinednull


let u: undefined = undefined;
let n: null = null;

默认情况下nullundefined是所有类型的子类型。 就是说你可以把nullundefined赋值给number类型的变量。

例如下面的代码,在TS中是完全可以执行的。

let userName: string;
userName = "搞前端的半夏";  // OK
userName = null;      // OK
userName = undefined; // OK

let age: number;
age = 18;        // OK
age = null;      // OK
age = undefined; // OK

let isBoy: boolean;
isBoy = true;      // OK
isBoy = false;     // OK
isBoy = null;      // OK
isBoy = undefined; // OK

在编程过程成空指针是最常见的bug之一,但是在TypeScript中我们无法使用具体的类型来表示特定的变量不能为空!幸运的是,TypeScript 2.0 解决了这个问题!。

strictNullChecks

TypeScript 2.0 增加了对不可为空类型的支持。有一种新的严格空值检查模式,他提供了strictNullChecks

来限制对空值的检查。可以通过在命令行上添加--strictNullChecks参数来启功严格空值检查。也可以在项目的tsconfig.json文件中启用strictNullChecks编译器选项。

在TS中,为了各版本的兼容,strictNullChecks的默认值是false

{
  "compilerOptions": {
    "strictNullChecks": true
    // ...
  }
}

在TS官方的演练场中你可以勾选strictNullChecks来启用严格空值检查!image-20220306223611971

注意点1

在严格空值检查模式下,null和undefined无法赋值给其他类型的变量

例如下面的代码在*strictNullChecks=true下,是无法编译通过的。

let userName: string;
userName = "搞前端的半夏";  // OK
userName = null;      // OK
userName = undefined; // OK

image-20220306223913935

注意点2

严格空值检查并不意味着变量的类型无法设置为null和undefined

例如下面的代码在*strictNullChecks=true下,正常编译通过的。

let userName: null;
userName = null;  

let age: undefined;
age = undefined;  

image-20220306224456016

变量如何可以为空

在正常的编程中,我们并不会直接将一个变量的类型设置为null或者undefined,例如username,我们通常设置为string类型。

如果我们想要username可以接受空值我们该怎么办呢?

1. 使用联合类型

联合类型(Union Types)表示取值可以为多种类型中的一种。

对于下面的代码,userName可以接受null类型的值。但是无法接受undefined的值

let userName: string | null;
userName = "搞前端的半夏";  // OK
userName = null;      // OK
userName = undefined; // Error

image-20220306225028895

2. a? 默认undefined

联合类型可以在Object中使用

type User = {
  name: string ;
  age:number | undefined
};

这里我们设置age的类型为number和undefined。

下面的两种用法都是正确的。


let user1: User = { name: "搞前端的半夏", age: undefined };
let user2: User = { name: "搞前端的半夏", age: 18 };

如果我们想要下面的效果,不需要手动给age赋值

let user2: User = { name: "搞前端的半夏"};

此时我们就需要用到**?**来使属性成为可选,这样我们就可以完全省略age属性的定义。


type User = {
  name: string ;
  age?:number 
};

请注意,在这种情况下:undefined类型会自动添加到联合类型中。因此,以下所有赋值都是正确的:

let user1: User = { name: "搞前端的半夏", age: undefined };
let user2: User = { name: "搞前端的半夏", age: 18 };
let user3: User = { name: "搞前端的半夏"};

安全检查

变量可空的安全检查

如果变量的类型包含nullor undefined,则访问任何属性都会产生编译时错误:

function UserNameLength(userName: string | null) {
  return userName.length;
}

image-20220306232041298

所以在访问属性之前,必须要先判断变量的值是否为空!

function UserNameLength(userName: string | null) {
  if (userName === null) {
    return 0;
  }

  return userName.length;
}

#可空类型的函数调用

在JS中支持回调函数,所以函数的参数会可能是函数类型,

function fn(callback?: () => void) {
  callback();
}

如果该参数是可选的函数类型,TS会将该参数加上undefined类型。

image-20220306232605352

那么这个函数的我们在调用函数的时候会报错!

image-20220306232526506

类似于在访问属性之前检查对象,我们需要首先检查函数是否具有非空值:

function fn(callback?: () => void) {
  if (callback) {
    callback();
  }
}

总结

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。