理解并使用 TypeScript 中的 NonNullable 工具类型

先说说一个常见的问题,你有如下的一个数组:

type NullableNumber = number | null | undefined;
const nullableNumbers: ReadonlyArray<NullableNumber> = [123nullundefined];

该数据中既有 number ,又有 nullundefined

现在,你想把该数组中的 number 都过滤出来形成一个新的数组,所以你写下了如下代码:

const numbers: ReadonlyArray<number> = nullableNumbers
    .filter(n => n !== null && n !== undefined);

奇怪的是,编辑器报了一条错误,提示类型不匹配:

理解并使用 TypeScript 中的 NonNullable 工具类型

尽管它在运行时是正确的,但 TypeScript 没能理解你的代码。

这个问题,我们可以用 type guard 来解决,即给 filter 函数声明返回值的类型:

const numbers: ReadonlyArray<number> = nullableNumbers
    .filter((n): n is number => n !== null && n !== undefined);

缺点是,这里的 n is number 是写死的。其实,我们也可以写一个更加通用的 nonNullable filter 函数:

// 通用的 nonnullable filter 函数
const isNonNullable = <T,>(t: T): t is NonNullable<T> => t !== null && t !== undefined;

// 这样使用
const nonNullableNumbers: ReadonlyArray<number> = nullableNumbers.filter(isNonNullable);

注意 <T,> 里的逗号,没有它,TypeScript 会误以为这是个 React Tag ,导致解析错误:

理解并使用 TypeScript 中的 NonNullable 工具类型

写到这里,你可能会好奇 NonNullable 是什么玩意。

理解 NonNullable

查看 TypeScript 文档,NonNullable 是 Utility Types 的一种。官方对它的解释是 NonNullable<Type> 会将 nullundefinedType 中排除掉,由剩余类型组成一个新的类型。

所以,如果我们有:

type Foo = number | null | undefined;

那么 NonNullable<Foo> 就会和 number 就是同一类型:

理解并使用 TypeScript 中的 NonNullable 工具类型

你可能会好奇 NonNullable 是如何定义的。比如,我可能会把它定义为:

type MyNonNullable<T> = Exclude<T, null | undefined>

这样写没问题,但官方给的定义是这样的:

type NonNullable<T> = T extends null | undefined ? never : T

它把我搞蒙了,因为按这个定义,NonNullable<number | null | undefined> 应该返回 never,因为 number | null | undefined extends null | undefined 显然是 true。你说是不是?

但实际上,这个定义不能这么理解:不能把 number | null | undefined 看成一个整体,而是一个由这3种类型构成的一个类型(可以是 number,也可以是其它2个),而 NonNullable 的作用,就是从这些类型中排除 nullundefined 类型,用剩下的类型组成新的类型。

文章参考

  • 官方 NonNullable 文档[1]
  • Stackoverflow 问答[2]
  • Medium 博客:Nullability in TypeScript[3]

参考资料

[1]

官方 NonNullable 文档: https://www.typescriptlang.org/docs/handbook/utility-types.html?#nonnullabletype

[2]

Stackoverflow 问答: How to understand NonNullable in typescript?: https://stackoverflow.com/questions/65147309/how-to-understand-nonnullable-in-typescript

[3]

Medium 博客:Nullability in TypeScript: https://gregoryppabian.medium.com/nullability-in-typescript-60be8c5a6d87


原文始发于微信公众号(背井):理解并使用 TypeScript 中的 NonNullable 工具类型

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/246925.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!