TypeScript 中 `{}`、`Object`、`object`、对象字面量类型,它们的区别是?

975 阅读4分钟

{} 即:空对象字面量类型,Object 即:原型类型,object 即:引用类型,以及对象字面量类型。这样更能从字面区分它们,帮助理解,😬。

空对象字面量类型

const a: {} = new Date;
const b: {} = true;
const c: {} = {
  toString() {
    return 1;
  }
}

nullundefined不能赋值给空对象字面量类型,除了它俩之外的任何类型( JavaScript 数据类型 中的原始 & 引用类型)都可以赋值给空对象字面量类型。

因为是兜底类型,太宽泛,可以赋值多种类型,进而可以包含跨类型的操作,所以不太安全,使用类型系统本就是为了精确类型界限,应尽量 避免使用

Object 类型

const a: Object = new Date;
const b: Object = true;
const c: Object = {
  toString() {
    return 'world';
  }
}

我们将 TypeSript 中的 Object 类型叫作:原型类型。会容易理解些,确实也应该这么翻译。

在 JavaScript 中,几乎所有的对象都是 Object 类型的实例,这里说的 Object 是 JavaScript 的一种 数据类型,不要与 TypeSript 中的原型类型混淆了,英文字面上看上去差不多。这些实例都会从 Object.prototype 继承属性和方法,虽然大部分属性都会被覆盖(shadowed)或者说被重写了(overridden)。这里提到了 Object.prototype 上的属性、方法,也是关键。TypeScript 中的原型类型约束的是:赋值必须符合原型内置的那些属性、方法的类型。需要覆写、扩展原型时,就可以使用这个类型,或许还有其它使用场景。

但是空对象字面量类型没有这个限制。回头再看看空对象字面量类型的代码示例,运行下看看是不是。🤓

其它的与 “空对象字面量类型” 基本一样,同样应尽量 避免使用

object 类型

const a: object = {};
const b: object = [];
const c: object = new Date;
const d: object = {
  toString() {
    return 1;
  }
}

我们将 TypeSript 中的 object 类型叫作:引用类型。与把 TypeSript 中的 Object 类型叫作 “原型类型” 一样,会容易理解些,确实也应该这么翻译。

nullundefinedJavaScript 数据类型 中的 原始类型 不能赋值给 object 类型,除此之外的任何类型,或者说需要一个对象( JavaScript 数据类型中的引用类型),但对对象的结构没有要求,都可以赋值给 TypeScript 中的引用类型。

与空对象字面量类型、Object的区别就是,JavaScript 数据类型 中的 原始类型 不能赋值给 TypeScript 中的引用类型。感觉说了一句废话但又不是废话的废话,🤪。

对象字面量类型

let c: {
  firstName: string
  lastName: string
};

class Person {
  constructor (
    public firstName: string,
    public lastName: string
  ) {}
}

c = {
  firstName: 'John',
  lastName: 'Smith'
};

c = new Person('Andromeda', 'Galaxy');

对象字面量类型,是在 描述对象的具体结构,即:这个东西的结构是这样的。

nullundefined不可以赋值给该类型,原始类型 也不可以。

引用类型的话,JavaScript 自身采用的就是结构化类型,TypeScript 直接沿用,所以只有结构符合这个类型定义的,才能赋值给这个类型,无论是简单对象(使用 {} 创建),还是复杂对象(使用 new 创建),或者说赋值给这个类型的值可能是对象,也可能是类(语法糖,背后使用的仍然是原型和构造函数的概念)。

绝大多数情况应该使用对象字面量类型。尽量避免使用空对象字面量类型、Object 类型、object 类型。

这里强烈推荐精读《JavaScript 高级程序设计》 中 “对象、类与面向对象编程” 章节(第 8 章)。

层次

unknown > any > {}(空对象字面量类型) > Object(原型类型) > object(引用类型) > 对象字面量类型。

附言一

>: 符号的含义可能需要介绍下。A >: B,A 类型是 B 类型的超类型,或者同种类型。A <: B,A 类型是 B 类型的子类型,或者同种类型。

附言二

这篇文章也可以回答一个问题:TS 中声明对象类型有哪些方式?

附言三

学习 TypeScript 想通畅些、高效些,并取得较好的成果,一定要同时精学《JS 高级程序设计》。对象的结构、数据类型等等概念在 JS 中本来就有,TS 只是基于他们提供了描述类型、操作类型方式,就好像语法糖,或者使用最新 ECMAScript 规范编写 JS 代码一样,换了个外壳,同一个东西,只是形式不同,前者内在,后者外在,在学习的过程中,遇到类似 “指定若干类型的区别”、“为什么这样操作类型” 等,对 JS 的理解就会变成直接的答案,由内而外,如丝般顺滑。

附言四

打算将我的笔记都以文章的形式发布出来,与大家分享,更多(80%)还是想交流,集思广益,另外也想结识些志趣相投的新朋友,好朋友,🫵🏼,我知道你就在那儿,快联系我吧!😬(微信:iyoooooooo

👣