关于TypeScript {}类型的问题--到目前为止,我认为它意味着“空对象没有属性”类型,但最近我偶然发现了禁止使用{}类型的eslint规则,因为它意味着“任何非空值”。打字稿操场上的快速测试表明这是真的:
let d: {} = {};
d = false;这段代码没有给出编译器错误,但是当我试图将null赋值给d时,确实存在一个错误。所以我的问题是:
{}在TypeScript中到底是什么类型?它真的代表“任何非零值”(在TypeScript文档中找不到确认)吗?发布于 2020-12-15 14:29:34
1. TypeScript中的实际{}类型是什么?它真的代表“任何非零值”(在TypeScript文档中找不到确认)吗?
如果您执行console.log(typeof(d));,那么您将看到{}是object类型的。不过,这并不完全正确,但让我先解释一下对象。首先,具有小写object的o可以是任何非原语值,而大写O的Object可以通过Object.prototype包含任何原语值。
因此,如果您试图用原语值覆盖对象,它会产生错误,因为它不喜欢原语值,虽然null也会像object类型一样工作,但是未定义的对象类型是未定义的,但是可以始终分配它。
现在,{}被称为“对象文本”--实际上是object和Object。这就是为什么原语和非原语值都可以分配给帕克特中提到的对象文本的原因。
因此,通常任何值都可以赋值给对象文本。
您可以在下面的stackblitz中检查这一点。
2.我应该如何实际键入“空对象而没有任何属性”?
可能有几种方法可以做到这一点,我知道的是,您可以像以前那样实例化它,或者做:let d = {};,因为类型是自动确定的,所以不需要添加类型。
另一种方法是在属性已知时使用接口定义属性,但通过在属性名称后面添加问号使其成为可选的。这使得使用非常容易,因为您的所有属性都是已知的,并且可以被intellisense找到。
示例:
export interface User {
name?: string;
email?: string;
}
let user: User = {};
user.name = "Joe";
user.email = "joe@hotmail.com";如果你的问题没有得到足够的回答,那就随便问吧!
Ps:有关对象的更多信息,请查看2度
更新#1
正如Paddokt在注释中提到的那样,如果您希望将对象键入为空对象或只键入特定对象,那么上面的示例将无法工作,因此需要一种不同的方法。
如果希望上面的示例仅为用户或空对象,则必须将用户对象包装在另一个对象中,如下所示:
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有一个用户对象,要么它根本没有一个对象,因为在这里用户本身不可能是一个空对象。
发布于 2020-12-15 16:08:39
TypeScript常见问题已经提到这一点:
https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-all-types-assignable-to-empty-interfaces
类型{}没有属性,布尔类型具有相同的特性:没有属性。
现在看到逻辑了吗?
实际上,可以尝试在布尔/数字上查找属性。
下面是您所期望的代码:
{}.a;
'a' in {};这两个表达式分别是undefined和false。
然而,让我们做一些愚蠢的事情,我们用一个数字和一个布尔值来交换它:
0.0.a;
'a' in 0.0;
true.a;
'a' in true;他们给出的结果还是一样的,不会有什么不同。
因此,由于它们不会抛出,所以它们可以安装到{}的任何位置,并且它们将返回所有所需属性的未定义的属性。
现在拿着这些:
null.a;
undefined.a;
'a' in null;而且您有运行时错误,因此它们不能模拟空对象{};
因为我给了上面的..。不可能得到一个空对象。
空原型问题尚未解决,因此我们没有这个表达式的类型:Object.create(null)。
类型推断仍然会导致同样的问题:
let x = {};x被扣减为{},没有帮助。
const x: Record<never, never> = true;对我们来说是个失败。
似乎没有解决办法。
发布于 2020-12-16 19:29:43
这是最新的打字本声明标准。
let d: Record<string, unknown>; // will default to {} value
d.whatever = 'hello';https://stackoverflow.com/questions/62397594
复制相似问题