Bij het werken met de FormData-interface in JavaScript, waarbij gegevens worden toegevoegd als sleutel/waarde-paren, is er geen ingebouwde manier om typeveiligheid af te dwingen op de sleutels die je toevoegt. Dit kan leiden tot typfouten, ontbrekende sleutels en onverwachte runtime-fouten. Maar in TypeScript kunnen we dit oplossen door strikte validatie van de sleutels af te dwingen.

Ik had deze oplossing zelf nodig toen ik mijn formulierwaarden naar een API stuurde. Ik realiseerde me later dat ik meerdere typfouten had gemaakt in meer dan één sleutel/waarde-paar dat ik probeerde toe te voegen aan mijn payload. Omdat FormData elke willekeurige tekenreeks accepteert als sleutel, kon ik de verkeerde tekenreeksen invoeren en doorgaan met het API-verzoek.

Nadat dit was gebeurd, zocht ik naar een manier om ervoor te zorgen dat TypeScript die fouten niet toestaat.

In dit artikel wordt getoond hoe je de sleutels van FormData typeveilig kunt maken met behulp van TypeScript.

Vereisten

Om het meeste uit dit artikel te halen, moet je een basiskennis hebben van de volgende zaken:

  1. JavaScript-programmering

  2. TypeScript-fundamenten, vooral hoe interfaces, types en de keyof-operator werken

  3. de FormData-interface

Als je nieuw bent in TypeScript of FormData, raad ik aan om eerst de officiële documentatie van TypeScript en de gids van MDN over FormData te bekijken voordat je verder gaat.

Stap 1: Definieer je toegestane sleutels

De oude manier

De standaard manier om gegevens toe te voegen met FormData is om dit handmatig te doen, met gewone strings:

const payload = new FormData();

payload.append("id", "1122");
payload.append("name", "Clark Kent");

payload.append("agge", "36"); // Typfout in sleutel is toegestaan

In de bovenstaande code snippet kun je zien dat er een typfout was bij het definiëren van een sleutel voor leeftijd. Maar TypeScript zal het niet markeren als een fout, en dit kan leiden tot fouten wanneer deze gegevens worden verzonden met een API-verzoek.

De betere manier

In plaats van de sleutels handmatig in te typen, definieer ze in een objectschema met een TypeScript-interface.

interface MyAllowedData {
    id: number;
    name: string;
    age: number;
}

Als alternatief kun je ze definiëren met types:

type MyAllowedData = {
    id: number;
    name: string;
    age: number;
}

Je kunt types of interfaces gebruiken, het is slechts een kwestie van voorkeur. Je kunt meer te weten komen over hoe ze verschillen in deze officiële TypeScript-documentatie playground.

Definieer vervolgens een unietype van elke sleutel in je interface.

type MyFormDataKeys = keyof MyAllowedData
// dit is hetzelfde als `type MijnFormDataSleutels = 'id' | 'naam' | 'leeftijd'`

De keyof operator helpt bij het maken van een unietype van de sleutels van een objecttype, dus het komt echt van pas als je niet handmatig een unietype wilt definiëren voor een groter object met veel sleutels.

Stap 2: Maak een Append Helper Functie

Nu je je strikt getypeerde sleutels hebt gedefinieerd, is de volgende stap het maken van een helperfunctie die ervoor zorgt dat alleen geldige sleutels aan FormData worden toegevoegd.

function appendToFormData (formData: FormData, key: MyFormDataKeys, value: string) {
  formData.append(key, value);
};

De appendToFormData functie neemt drie argumenten. Hier is hoe het allemaal werkt:

  • Het eerste argument, formData, is een instantie van het FormData-object. Dit is waar sleutel/waarde-paren worden toegevoegd voordat ze in een API-verzoek worden verzonden.

  • Het tweede argument, key, is de sleutelnaam van het veld dat je wilt toevoegen. Het type is MyFormDataKeys, het unietype dat we hebben gemaakt om ervoor te zorgen dat alleen die sleutels die we hebben gedefinieerd aan FormData worden toegevoegd.

  • Het derde argument is een string value die de waarde vertegenwoordigt die met de sleutel moet worden toegevoegd.

Merk op dat FormData alleen de string en Blob types als waarden accepteert in elk sleutel/waarde-paar. In deze handleiding werken we alleen met string waarden – maar houd in gedachten dat je blob waarden kunt gebruiken om bestanden toe te voegen aan API-verzoeken.

Laten we nu de functie testen:

const payload = new FormData();

appendToFormData(payload, "id", "19282"); // ✅ Toegestaan
appendToFormData(payload, "name", "Lenny Brown"); // ✅ Toegestaan
appendToFormData(payload, "age", "20"); // ✅ Toegestaan

appendToFormData(payload, "someOtherKey", "89"); // ❌ TypeScript Fout: Argument van type 'someOtherKey' is niet toewijsbaar.

Stap 3: Gebruik de Hulpfunctie na het Verzenden van het Formulier

Voeg nu onze velden toe aan FormData voordat je ze naar een API verzendt.

const handleSubmitForm = () => {
  const payload = new FormData();
   appendToFormData(payload, "id", "19282");
   appendToFormData(payload, "name", "Lenny Brown");
   appendToFormData(payload, "age", "20");

  // Verzend payload via API
  fetch("/api/submit", { method: "POST", body: payload });
};

Velden Toevoegen vanuit een Object

Als alternatief, als je al je volledige payload in een object hebt, kun je vermijden elk veld één voor één toe te voegen door de functie op deze manier te implementeren:

const handleSubmitForm = () => {
  // al je velden in een object
  const formValues: MyAllowedData = {
    id: 1123,
    name: 'John Doe',
    age: 56
  }
  const payload = new FormData();

  Object.entries(formValues).forEach(([key, value]) => {
    appendToFormData(payload, key as MyFormDataKeys, `${value}`); // gebruik template literals om de waarde door te geven
  });

  // Verzend payload via API
  fetch("/api/submit", { method: "POST", body: payload });
};

In de bovenstaande snippet gebruiken we Object.entries om over elk sleutel/waarde paar in een object te itereren, zodat het kan worden toegevoegd aan het FormData-object. Let op dat de waarde in elk paar, of het nu een string of een getal is, als een string wordt doorgegeven met behulp van template literals om een TypeScript type mismatch van het value argument in onze helperfunctie te voorkomen.

Conclusie

Door gebruik te maken van de keyof operator van TypeScript, kunnen we FormData.append() volledig type-veilig maken. Deze eenvoudige techniek helpt om sleutel mismatchen te voorkomen en maakt je API-aanvragen betrouwbaarder.

Laat me weten wat je van het artikel vindt, en voel je vrij om suggesties te doen die mijn oplossing kunnen verbeteren.

Bedankt voor het lezen!