【发布时间】:2021-09-03 21:46:37
【问题描述】:
Typescript 使用什么类型名称来表示“{}”形式的变量?
这对大多数人来说可能是非常明显的,但我是 Typescript 的新手,我正在转换一些 Javascript,而这个基本问题很难用谷歌搜索。所有其他基本类型都有很好的文档记录,但我找不到基本哈希类型的任何内容。我不确定它是“对象”还是“对象”或“地图”或“任何”。
【问题讨论】:
标签: typescript
Typescript 使用什么类型名称来表示“{}”形式的变量?
这对大多数人来说可能是非常明显的,但我是 Typescript 的新手,我正在转换一些 Javascript,而这个基本问题很难用谷歌搜索。所有其他基本类型都有很好的文档记录,但我找不到基本哈希类型的任何内容。我不确定它是“对象”还是“对象”或“地图”或“任何”。
【问题讨论】:
标签: typescript
出于所有意图和目的,空对象类型 ({}) 可以与 Object 类型互换。所有具有属性的值(即不是null 或undefined)都可以分配给Object 或{}。
另一方面,object 类型适用于所有非primitive 值,因此不能与Object 或{} 互换。
Map<KeyType, ValueType> 类型专门表示Map object。
最后,any 字面意思是 任何 值:它可以是原始值或非原始值、null 或未定义以及我在此处忽略的任何内容。
更多信息请参见Difference between 'object' ,{} and Object in TypeScript。
即使它们存在于 TypeScript 中,您很可能实际上并不想在代码中使用 {} 或 Object,对于 typescript,有一个特定的 eslint rule 提供了有关此的更多详细信息:
当您键入一个值作为{} 时,它会警告您:不要使用{} 作为类型。 {} 实际上意味着“任何非空值”。
Record<string, unknown>。unknown。Record<string, never>。当使用Object 时:不要使用Object 作为类型。 Object 类型实际上意味着“任何非空值”,因此它比 unknown 略好。
Record<string, unknown>。unknown。【讨论】:
{} 是一个对象字面量。 TypeScript 中的对象字面量几乎可以定义任何类型的对象。示例中的 empty 对象字面量(字面意思是 {})等价于类型 Object。但是其中包含属性的对象字面量为具有这些属性的对象定义了一个可能匿名的类型,而不仅仅是Object。 (有关 {}、Object 和 object 的更多信息,请参阅 Emma Koskinen 在 their answer 中链接的 this answer。)
理解 TypeScript 类型系统的关键之一是它是 structural(基于事物的形状),而不是 nominal(基于事物的名称)。例如:
interface Example {
a: number;
b: string;
}
function fn(x: Example) {
console.log(x.a, x.b);
}
const obj = {a: 42, b: "Life, the Universe, and Everything"};
fn(obj); // <=== No error here
没有说obj 是Example 类型,但这很好,因为它与Example 的赋值兼容,所以将它传递给fn 非常好。
事实上,我们可以更进一步,明确地说obj 是一个不同的类型:
interface Example {
a: number;
b: string;
}
function fn(x: Example) {
console.log(x.a, x.b);
}
interface AnotherExample {
a: number;
b: string;
c: boolean;
}
const obj: AnotherExample = {a: 42, b: "Life, the Universe, and Everything", c: true};
fn(obj); // <=== No error here
在那里,我们明确说obj 是AnotherExample 类型,它与Example (略有)不同。但是将它传递给fn 仍然很好,因为fn 所要求的只是对象具有Example 的形状(a: number; b: string;),而obj 具有。它有一个多余的属性c,但这与fn 无关。 fn 说它只关心 a 和 b。
【讨论】: