Record<K, V>
Last updated: 2026-10-22
Record<K, V> Record
Record<K, V> builds an object type with keys K and values V. K can be a literal union (enum lookup tables) or string/number (open-ended cache objects). Compared to hand-written index signatures, Record declares key and value types once and reuses them everywhere.
| Group | Utility Types |
|---|---|
| Kind | Type |
| Strict mode | Not required |
ℹ️ Info The editor transpiles TypeScript to JavaScript and runs it (no type checking); see each example's Output for type-check results.
📝 Syntax
type Record<K extends string | number | symbol, V> = {
[P in K]: V;
};
// Usage
type Timeout = Record<"dev" | "staging" | "prod", number>;
type Cache = Record<string, number>;
⚙️ Parameters
| K | The key type: a literal union makes every key required; string/number/symbol yields an open key set |
|---|---|
| V | The value type shared by every key |
Returns:A mapped type with one entry per member of K, all typed V.
▶ Example
Edit the code below and click Try it to see the transpiled result:
Output:
15000 3000
128
(Runtime output after transpilation; Record<Env, number> requires all three keys — omitting staging yields error TS2739)
💡 Notes
ℹ️ Info Implementation: type Record<K, V> = { [P in K]: V } — the mapped type turns every key of K into a V. Hence Record<"a"|"b", number> requires both a and b.
⚠️ Note Record<string, V> returns V (not V | undefined) for any key access, even when the key is absent. Under strict mode, enabling noUncheckedIndexedAccess adds undefined to indexed access results, which matches reality better.
💡 Tip To swap keys and values or derive a key union from an object: keyof typeof obj gives the key union, and Record<keyof typeof obj, NewValue> builds an isomorphic table — handy for mapping enum values to display text.
🏷️ Related Utility Types
💡 Related cases
More cases coming soon.
📚 Related tutorials
❓ FAQ
Q How does Record<K, V> differ from a { [key: string]: V } index signature?
A With a literal-union K, Record requires every key to be present (a completeness check) that index signatures lack; when K is string the two are type-equivalent. Use Record with a literal union when key completeness matters.
Q Can Record values differ per key?
A Record forces one shared V. For per-key value shapes use a mapped type: { [K in Env]: { url: string; retries: number } }, or declare a Config interface and reuse it via Record<Env, Config>.
Q Should I use a Map instead of Record?
A Depends: fixed keys, JSON serialization needs, and completeness checking favor Record; dynamically growing keys, non-string keys, and frequent add/remove favor Map<string, number>. Their type semantics differ — do not mix them casually.