空对象的索引签名和记录之间的区别? [英] Difference between index signature and Record for empty object?
问题描述
我无法弄清楚索引签名和记录类型之间的区别.有人可以解释一下这些区别以及何时使用另一种吗?
I cannot figure out the difference between index signatures and record types. Could someone explain the differences and when to use one versus the other?
具体来说,我希望定义一个对象的类型,该对象的键和值将具有随机字符串,这些字符串将被迭代.
Specifically, I am looking to define the type of an object that will have random strings for its keys and values, which will be iterated over.
是否有区别:
let objectVariable: Record<string, string> = {}
和
let objectVariable2: {[index: string]: string} = {}
推荐答案
Record
的定义是:
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
当创建像 type MyType = Record
这样的类型时,内联 Record
会导致以下类型:
When creating a type like type MyType = Record<string, string>;
, inlining Record
leads to the following type:
type MyType = {
[P in string]: string;
};
这是说创建一个对象类型,在集合 string
中使用字符串属性名称.由于 string
是无限的,所以字符串有无限的可能性(不像 "prop1" | "prop2"
这样的字符串文字类型的联合)......所以它描述了一个可以具有任意名称的任意数量的属性,唯一的限制是这些属性必须具有 string
类型.
This is saying to create an object type with string property names within the set string
. Since string
is unbounded there's unlimited possibilities of strings (unlike a union of string literal types like "prop1" | "prop2"
)... so it's describing an object that can have any number of properties with any name, with the only restriction being that the properties must have a type of string
.
所以是的,从类型检查的角度来看它基本上等同于没有映射类型的索引签名的示例 ({ [index: string]: string; }
.
So yes, from a type checking perspective it's basically equivalent to the example with the index signature without a mapped type ({ [index: string]: string; }
.
使用简单的索引签名
以这种方式使用 Record
有点奇怪,很多人可能不明白发生了什么.当可以有任意数量的属性时,表达意图的更常见方法是不使用映射类型:
Using Record
in this fashion is a little strange though and many people might not understand what's going on. A more common way to express intent when there can be any number of properties, is to not use a mapped type:
type ObjectWithStringProperties = {
[index: string]: string;
};
这有一个额外的好处,可以帮助解释密钥应该是什么.例如:
This has the added benefit of helping explain what the key is supposed to be. For example:
type PersonsByName = {
[name: string]: Person;
};
const collection: PersonsByName = {};
请注意,通过这种方式,类型是不同的,因为使用具有此类型的对象的开发人员将在其编辑器中查看这些额外描述的键名信息.
Note that in this way the types are different because a developer using an object with this type will have this extra described key name information to look at in their editor.
使用记录
请注意,Record
通常如下使用:
Note that Record
is usually used like the following:
type ThreeStringProps = Record<"prop1" | "prop2" | "prop3", string>;
// goes to...
type ThreeStringProps = { [P in "prop1" | "prop2" | "prop3"]: string; };
// goes to...
type ThreeStringProps = {
prop1: string;
prop2: string;
prop3: string;
};
这篇关于空对象的索引签名和记录之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!