{} 即:空对象字面量类型,Object 即:原型类型,object 即:引用类型,以及对象字面量类型。这样更能从字面区分它们,帮助理解,😬。
空对象字面量类型
const a: {} = new Date;
const b: {} = true;
const c: {} = {
toString() {
return 1;
}
}
null、undefined不能赋值给空对象字面量类型,除了它俩之外的任何类型( 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 类型叫作 “原型类型” 一样,会容易理解些,确实也应该这么翻译。
null、undefined、 JavaScript 数据类型 中的 原始类型 不能赋值给 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');
对象字面量类型,是在 描述对象的具体结构,即:这个东西的结构是这样的。
null、undefined不可以赋值给该类型,原始类型 也不可以。
引用类型的话,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)
👣