1. TypeScript 中的 {} 类型实际上是什么?它真的代表“任何非空值”吗(我在 TypeScript 文档中找不到确认)?
如果你执行 console.log(typeof(d));
,那么你会发现 {}
的类型是 object
。这并不完全正确,但让我先解释一下关于 object
的问题。首先,小写字母 o
的 object
可以是任何非原始值,而大写字母 O
的 Object
可以通过 Object.prototype
包括任何原始值。
因此,如果你尝试用原始值覆盖 object
,它会报错,因为它不喜欢原始值,虽然 null 作为一个 object
类型也可以工作,但是 undefined 是 undefined 类型,但是这总是可以被赋值。
现在{}
被称为“对象字面量”,实际上它是object
和Object
的组合。因此,正如packt所提到的那样,原始值和非原始值都可以分配给对象字面量。
因此,通常任何值都可以分配给对象字面量,除非启用了strictNullChecks,则在这种情况下无法分配null和undefined,如@RobbieSpeed在评论中提到的。
您可以在以下stackblitz中检查此内容,请注意此处未启用strictNullChecks。
2. 实际上应该如何输入“没有任何属性的空对象”?
有几种方法可以做到这一点,我知道的方法是您可以像您所做的那样进行实例化,或者执行let d = {};
,因为类型会自动确定,因此不需要添加类型。
另一种方法是使用接口来定义属性,当它们已知时,通过在属性名称后面添加问号使它们全部变为可选。
这样做不仅易于使用,而且所有属性都是已知的,并且可以通过智能感知找到。
示例:
export interface User {
name?: string;
email?: string;
}
let user: User = {};
user.name = "Joe";
user.email = "joe@hotmail.com";
如果这个回答没有充分解决您的问题,请随时提问!
附注:有关对象的更多信息,请查看2ality
更新 #1
正如Paddokt在评论中提到的,如果您想将对象作为空对象或仅特定对象进行输入,则上面的示例将无法工作,因此需要采用不同的方法。
如果您希望上面的示例仅为User或空对象,则必须将用户对象包装在另一个对象中,如下所示:
export interface optUser {
user?: User;
}
export interface User {
name: string;
email: string;
}
let optuser: optUser = {};
optuser.user = {
name: "Joe",
email: "joe@hotmail.com"
}
这样你就可以拥有一个变量,它可以是一个空对象,或者一个包含用户的对象,其中用户名和电子邮件地址都是必需的。
注意:
请注意,
optuser.user = {};
不起作用,要么 optuser 有一个用户对象,要么根本没有对象,因为在此处User本身不能是一个空对象。
let
允许你这样做。实际上,你是在说——让对这个空对象的引用消失,并用false值替换它。 - Pedro Filipe