Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

typescript - 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.

is there a difference between:

let objectVariable: Record<string, string> = {}

and

let objectVariable2: {[index: string]: string} = {}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The definition for Record is:

/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

When creating a type like type MyType = Record<string, string>;, inlining Record leads to the following type:

type MyType = {
    [P in string]: 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.

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; }.

Use a plain index signature

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.

Using 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;
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.6k users

...