Så väljer du mellan Record och Map i TypeScript

9 november 2026

Flödesschema för att välja mellan Map och Record i TypeScript. Hjälper dig att bestämma om du ska använda en typescript dictionary baserat på nycklar.

När en webbplats ska slå upp en produkt utifrån en kod behöver typen spegla hur uppslaget faktiskt fungerar. En TypeScript-dictionary passar ofta när nycklarna är strängar och värdena har samma form, men om nycklarna kan vara objekt eller saknas är valet mindre självklart.

Flödesschema för att välja mellan Map och Record i TypeScript. En typescript dictionary kan vara en Map eller Record beroende på nycklar och användning.

Välj struktur efter nycklarna och hur uppslaget ska fungera

  • Record passar när nycklarna är strängar och värdena delar en typ.
  • En begränsad nyckelunion gör att TypeScript kräver ett värde för varje angiven nyckel.
  • Map passar när nycklar kan vara objekt eller när du behöver metoder som set och delete.
  • Saknade uppslag behöver hanteras uttryckligen, särskilt när data kommer från användare eller ett API.

Record passar bäst när nycklarna är strängar

En kod som "se-104" eller ett produktnamn fungerar bra som objektets nyckel. Med Record anger du vilken typ nycklarna och värdena ska ha, utan att skriva en indexsignatur manuellt.

type Product = {
  name: string;
  price: number;
};

const products: Record = {
  "se-104": { name: "Anteckningsbok", price: 49 },
};

const product = products["se-104"];

TypeScripts dokumentation om Record beskriver typen som ett objekt vars nycklar och värden följer de typer du anger. Jag tycker att Record är den tydligaste starten när en webbplats behöver ett enkelt uppslag mellan strängar och strukturerade värden.

Men Record säger inte att varje möjlig sträng faktiskt finns i objektet. Det är skillnaden mellan typen av ett värde och förekomsten av en viss nyckel, och den kan bli viktig när koden får data utifrån.

En nyckelunion gör obligatoriska poster tydliga

Om uppsättningen nycklar är känd i förväg kan du låta typen fånga ett vanligt misstag: att glömma en post eller stava en nyckel fel. Här fungerar en union av strängliteraler bättre än en generell strängnyckel.

type Locale = "sv" | "en";

const labels: Record = {
  sv: "Lägg i varukorgen",
  en: "Add to cart",
};

Med den här typen förväntar sig TypeScript båda språken. Om en saknas i objektet eller ersätts med exempelvis eng, får du ett typfel. Det passar för fasta konfigurationer, som språktexter eller namngivna statusar, men inte för produktkoder som förändras över tid.

Det är också här en vanlig sammanblandning uppstår: en strängindexsignatur eller Record beskriver ett öppet nyckelutrymme, medan en union av några få nycklar begränsar vilka namn som är tillåtna. TypeScripts avsnitt om indexsignaturer tar även upp att alla egenskaper i objektet måste passa den angivna värdetypen.

Map är bättre när nycklarna inte är vanliga strängar

Två objekt kan ha samma innehåll men ändå behöva fungera som två olika nycklar. Ett vanligt JavaScript-objekt omvandlar nycklar till strängar, medan Map kan använda objekt som nycklar och skilja mellan deras identiteter.

const firstUser = { id: 7 };
const secondUser = { id: 7 };

const sessions = new Map();
sessions.set(firstUser, "session-a");

sessions.get(firstUser);  // "session-a"
sessions.get(secondUser); // undefined

Trots att objekten har samma egenskaper är de två separata objekt, så uppslaget med secondUser hittar ingen post. ECMAScript-specifikationen beskriver Map som en samling nyckel- och värdepar där nyckeln kan vara ett godtyckligt värde.

Map har också inbyggda metoder för att lägga till, läsa, ta bort och iterera poster. Jag skulle välja Map för en tillfällig cache där nyckeln är ett objekt eller där poster ofta läggs till och tas bort; för en enkel JSON-liknande samling med textnycklar är ett objekt oftast smidigare.

Ett uppslag kan saknas även när typen säger Product

En rad som products[sku] ser självklar ut, men en godtycklig SKU behöver inte finnas i objektet. Med strängindexering kan TypeScript utan extra inställning behandla resultatet som värdetypen, trots att körningen kan ge undefined.

Aktivera noUncheckedIndexedAccess om du vill att typkontrollen ska ta hänsyn till att en indexerad nyckel kan saknas. Då blir det lättare att upptäcka kod som försöker läsa exempelvis product.name innan uppslaget har kontrollerats.

Situation Trolig följd Gör så här
Nyckeln är en känd strängunion En bortglömd post kan ge typfel. Använd Record.
Nyckeln kommer från ett formulär eller API Uppslaget kan saknas och ge undefined. Kontrollera resultatet innan värdet används.
Nyckeln är ett objekt Ett vanligt objekt passar inte för identitetsbaserade uppslag. Använd Map.
Objektet innehåller både fasta fält och extra nycklar En indexsignatur kan tvinga de fasta fälten att ha samma värdetyp. Lägg de dynamiska posterna i en egen egenskap.

En säker läsning kan se ut så här:

const product = products[sku];

if (product === undefined) {
  return "Produkten kunde inte hittas";
}

return product.name;

TypeScripts versionsinformation för 4.2 visar varför ett uppslag kan bli undefined när en nyckel saknas, och hur noUncheckedIndexedAccess gör den möjligheten synlig i typen. Det är särskilt användbart när en nyckel hämtas från URL:en eller en sökruta.

Håll fasta fält åtskilda från dynamiska nycklar

En indexsignatur gäller alla egenskaper som matchar nyckeltypen. Om ett objekt både har ett fast fält som name: string och godtyckliga numeriska värden kan typen därför bli svår att få ihop.

type ProductStats = {
  name: string;
  counts: Record;
};

Här ligger produktens namn och de dynamiska räknarna på olika nivåer. Den uppdelningen gör typen lättare att läsa och hindrar att ett fast textfält blandas ihop med de numeriska värdena i dictionaryn. Samma mönster passar när en inställning har några obligatoriska egenskaper plus en samling extra data.

För data som skickas som JSON bör typen dessutom inte ses som validering av innehållet. TypeScript kontrollerar koden vid kompilering, men den kan inte på egen hand bevisa att ett externt svar verkligen följer typen när det körs. Kontrollera därför data vid gränsen där den kommer in, innan den används som en dictionary.

Välj den struktur som gör fel synliga

Om nycklarna är kända i förväg ger en begränsad Record tydligast skydd mot saknade poster. För varierande textnycklar är Record bekvämt, men hantera saknade uppslag; välj Map när nycklarna behöver vara objekt eller när Map-metoderna passar arbetsflödet.

För en webbplatskatalog med produktkoder skulle jag välja ett objekt med en tydlig värdetyp och kontrollera uppslagets resultat. För sessionsdata som indexeras med användarobjekt skulle jag välja Map. Den bästa dictionaryn är den som gör det svårt att använda ett saknat eller feltypat värde av misstag.

Vanliga frågor

Använd Record när produktkoderna är strängar och alla värden har samma form, till exempel ett namn och ett pris. Typen beskriver inte att varje möjlig kod finns, så kontrollera om uppslaget ger undefined innan du använder produkten.
En begränsad union, exempelvis "sv" | "en", gör nycklarna fasta. Record kräver då en post för varje språk och TypeScript kan upptäcka om en post saknas eller har felstavat nyckeln. Det passar för konfigurationer, men inte lika bra för produktkoder som ändras över tid.
Välj Map när nycklarna kan vara objekt och uppslaget ska skilja mellan deras identiteter. Två separata objekt med samma egenskaper räknas som olika nycklar. Map har också metoder som set och delete, vilket kan passa en cache där poster läggs till och tas bort ofta.
Kontrollera resultatet innan du läser egenskaper: om products[sku] är undefined kan du exempelvis returnera ett meddelande om att produkten inte hittades. TypeScript-inställningen noUncheckedIndexedAccess gör att risken för saknade nycklar syns i typen. Validera också externa JSON-data när de kommer in, eftersom TypeScript inte verifierar dem vid körning.
Betygsätt artikeln

Genomsnitt: 5.0 / 5 · 2 betyg

Taggar

typescript record map indexsignaturer typkontroll
Kommentarer (0)
Lägg till en kommentar