Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【TypeScript 演化史 -- 1】non-nullable 的类型 #144

Open
husky-dot opened this issue Nov 11, 2019 · 0 comments
Open

【TypeScript 演化史 -- 1】non-nullable 的类型 #144

husky-dot opened this issue Nov 11, 2019 · 0 comments

Comments

@husky-dot
Copy link
Owner

作者:Marius Schulz
译者:前端小智
来源:Marius Schulz

在这篇文章中,我们将讨论发布于 TypeScript 2.0 中的 non-nullable 类型,这是对类型系统的一个重大的改进,该特性可对 nullundefined 的检查。cannot read property 'x' of undefinedundefined is not a function 在 JS 中是非常常见的错误,non-nullable 类型可以避免此类错误。

null 和 undefined 的值

TypeScript 2.0 之前,类型检查器认为 nullundefined 是每种类型的有效值。基本上,nullundefined 可以赋值给任何东西。这包括基本类型,如字符串、数字和布尔值:

let name: string;
name = "Marius";  // OK
name = null;      // OK
name = undefined; // OK

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

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

number 类型为例。它的域不仅包括所有的IEEE 754浮点数,而且还包括两个特殊的值 nullundefined

对象、数组和函数类型也是如此。无法通过类型系统表示某个特定变量是不可空的。幸运的是,TypeScript 2.0 解决了这个问题。

严格的Null检查

TypeScript 2.0 增加了对 non-nullable 类型的支持,并新增严格 null 检查模式,可以通过在命令行上使用 ——strictNullChecks 标志来选择进入该模式。或者,可以在项目中的 tsconfig.json 文件启用 strictnullcheck 启用。

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

在严格的 null 检查模式中,nullundefined 不再分配给每个类型。nullundefined 现在都有自己的类型,每个类型只有一个值

如果咱们在编译前时启用了严格的 null 检查,如果将 nullundefined 分配给任何变量都会导致类型错误

// 使用 --strictNullChecks 编译

let name: string;
name = "Marius";  // OK
name = null;      // Error
name = undefined; // Error

let age: number;
age = 24;        // OK
age = null;      // Error
age = undefined; // Error

let isMarried: boolean;
isMarried = true;      // OK
isMarried = false;     // OK
isMarried = null;      // Error
isMarried = undefined; // Error

那么,如何在 TypeScript 2.0 中使变量为空?

用联合类型构建可空性

由于在启用严格的 null 检查时,类型在默认情况下是不可空的,所以我们需要显式指定可为空,并告诉类型检查器我们希望哪些变量为空。我们通过构造一个包含 nullundefined 类型的联合类型来实现这一点

let name: string | null;
name = "Marius";  // OK
name = null;      // OK
name = undefined; // Error

注意,undefined 不是 name 变量的有效值,因为联合类型不包含 undefined 类型

这种可空性方法的一大优点是,类型中哪些成员是可空的变得很明显,并且可以自文档化。以这个简单的 User 类型为例:

type User = {
  firstName: string;
  lastName: string | undefined;
};

let jane: User = { firstName: "Jane", lastName: undefined };
let john: User = { firstName: "John", lastName: "Doe" };

我们可以通过添加 ?lastName 属性设为可选。这样就可以完全省略 las​​tName 属性的定义。 此外,undefined 的类型会自动添加到联合类型中。 因此,以下所有分配类型都是可以的:

type User = {
  firstName: string;
  lastName?: string;
};

// 可以为 lastName 属性分配一个字符串
let john: User = { firstName: "John", lastName: "Doe" };

// 或者 undefined
let jane: User = { firstName: "Jane", lastName: undefined };

// 还可以省略
let jake: User = { firstName: "Jake" };

可为空类型的属性访问

如果对象的类型包括 nullundefined,则访问任何属性都会产生编译时错误:

function getLength(s: string | null) {
  // Error: Object 可能为空
  return s.length;
}

在访问属性之前,需要使用类型保护来检查给定对象上的属性访问是否安全:

function getLength(s: string | null) {
  if (s === null) {
    return 0;
  }

  return s.length;
}

TypeScript 是兼容 JS ,并支持条件表达式中的类型保护,所以这种方法也可以:

function getLength(s: string | null) {
  return s ? s.length : 0;
}

使用可空类型的函数调用

如果试图调用包含 nullundefined 类型的函数,则会产生编译时错误。下面的callback 参数是可选的(注意?),所以它可能 undefined。因此,它不能被直接调用

function doSomething(callback?: () => void) {
  // Error: 不能调用可能是 “undefined” 的对象
  callback();
}

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

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

还可以用 typeof 检查返回的值

function doSomething(callback?: () => void) {
  if (typeof callback === "function") {
    callback();
  }
}

总结

Non-nullable 类型是 TypeScript 类型系统的基础和有价值的补充。它们允许对哪些变量和属性可以为空进行精确构建。只有在类型保护将属性访问或函数调用确定为安全之后,才允许进行属性访问或函数调用,从而避免了许多编译时的可空性错误。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

原文:https://mariusschulz.com/blog/non-nullable-types-in-typescript

好课推荐 介绍
周爱民老师出新课了,想当初还是看他的书入门的,这次新课大纲不错,强烈推荐啊,使用 ILOVEJSJS 优惠码再便宜5

##交流(欢迎加入群,群工作日都会发红包,互动讨论技术)

阿里云最近在做活动,低至2折,有兴趣可以看看:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pxuujn3r

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

https://github.com/qq449245884/xiaozhi

因为篇幅的限制,今天的分享只到这里。如果大家想了解更多的内容的话,可以去扫一扫每篇文章最下面的二维码,然后关注咱们的微信公众号,了解更多的资讯和有价值的内容。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant