返回介绍

装箱类型

发布于 2024-09-11 00:55:48 字数 1862 浏览 0 评论 0 收藏 0

string 类型会是 String 类型的子类型,String 类型会是 Object 类型的子类型,中间还有一个奇怪的 {}。

type Result14 = string extends String ? 1 : 2; // 1
type Result15 = String extends {} ? 1 : 2; // 1
type Result16 = {} extends object ? 1 : 2; // 1
type Result18 = object extends Object ? 1 : 2; // 1

{} 不是 object 的字面量类型吗?为什么能在这里比较,并且 String 还是它的子类型?

把 String 看作一个普通的对象,上面存在一些方法,如:

interface String {
  replace: // ...
  replaceAll: // ...
  startsWith: // ...
  endsWith: // ...
  includes: // ...
}

这时是不是能看做 String 继承了 {} 这个空对象,然后自己实现了这些方法?当然可以!

在结构化类型系统的比较下,String 会被认为是 {} 的子类型。这里从 string < {} < object 看起来构建了一个类型链,但实际上 string extends object 并不成立:

type Tmp = string extends object ? 1 : 2; // 2

由于结构化类型系统这一特性的存在,会得到一些看起来矛盾的结论:

type Result16 = {} extends object ? 1 : 2; // 1
type Result18 = object extends {} ? 1 : 2; // 1

type Result17 = object extends Object ? 1 : 2; // 1
type Result20 = Object extends object ? 1 : 2; // 1

type Result19 = Object extends {} ? 1 : 2; // 1
type Result21 = {} extends Object ? 1 : 2; // 1

16-18 和 19-21 这两对,为什么无论如何判断都成立?难道说明 {} 和 object 类型相等,也和 Object 类型一致?

当然不,这里的 {} extends 和 extends {} 实际上是两种完全不同的比较方式。

{} extends object 和 {} extends Object 意味着, {} 是 object 和 Object 的字面量类型,是从类型信息的层面出发的,即字面量类型在基础类型之上提供了更详细的类型信息。

object extends {} 和 Object extends {} 则是从结构化类型系统的比较出发的,即 {} 作为一个一无所有的空对象,几乎可以被视作是所有类型的基类,万物的起源。

如果混淆了这两种类型比较的方式,就可能会得到 string extends object 这样的错误结论。

而 object extends Object 和 Object extends object 这两者的情况就要特殊一些,它们是因为“系统设定”的问题,Object 包含了所有除 Top Type 以外的类型(基础类型、函数类型等),object 包含了所有非原始类型的类型,即数组、对象与函数类型,这就导致了你中有我、我中有你的神奇现象。

由此得出结论:原始类型 < 原始类型对应的装箱类型 < Object 类型。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文