Beim Arbeiten mit dem FormData-Interface in JavaScript, wo Daten als Schlüssel/Wert-Paare hinzugefügt werden, gibt es keine eingebaute Möglichkeit, die Typensicherheit der hinzugefügten Schlüssel durchzusetzen. Das kann zu Tippfehlern, fehlenden Schlüsseln und unerwarteten Laufzeitfehlern führen. Aber in TypeScript können wir dieses Problem lösen, indem wir eine strenge Schlüsselvalidierung durchsetzen.
Ich benötigte diese Lösung selbst, als ich meine Formularwerte an eine API sendete. Später stellte ich fest, dass ich mehrere typografische Fehler in mehr als einem Schlüssel/Wert-Paar gemacht hatte, das ich zu meiner Nutzlast hinzufügen wollte. Da FormData jeden String als Schlüssel akzeptiert, konnte ich die falschen Strings übergeben und mit der API-Anfrage fortfahren.
Nachdem dies passiert war, suchte ich nach einer Möglichkeit, sicherzustellen, dass TypeScript diese Fehler nicht zulässt.
Dieser Artikel zeigt Ihnen, wie Sie FormData
-Schlüssel typensicher mit TypeScript machen können.
Voraussetzungen
Um den größtmöglichen Nutzen aus diesem Artikel zu ziehen, sollten Sie ein grundlegendes Verständnis der folgenden Themen haben:
-
JavaScript-Programmierung
-
Grundlagen von TypeScript, insbesondere wie Interfaces, Typen und der
keyof
-Operator funktionieren -
das FormData-Interface
Wenn Sie neu in TypeScript oder FormData sind, empfehle ich, sich die offizielle Dokumentation von TypeScript und den Leitfaden von MDN zu FormData anzusehen, bevor Sie fortfahren.
Schritt 1: Definieren Sie Ihre erlaubten Schlüssel
Der alte Weg
Der Standardweg, Daten mit FormData anzuhängen, besteht darin, dies manuell mit einfachen Zeichenfolgen zu tun:
const payload = new FormData();
payload.append("id", "1122");
payload.append("name", "Clark Kent");
payload.append("agge", "36"); // Tippfehler im Schlüssel ist erlaubt
Im obigen Code-Schnipsel sehen Sie, dass ein Tippfehler beim Definieren eines Schlüssels für age
auftrat. TypeScript markiert dies jedoch nicht als Fehler, was zu Fehlern führen könnte, wenn diese Daten mit einer API-Anfrage gesendet werden.
Der bessere Weg
Statt die Schlüssel manuell einzugeben, definieren Sie sie in einem Objektschema mit einer TypeScript-Schnittstelle.
interface MyAllowedData {
id: number;
name: string;
age: number;
}
Alternativ können Sie sie mit Typen definieren:
type MyAllowedData = {
id: number;
name: string;
age: number;
}
Sie können entweder Typen oder Schnittstellen verwenden, es ist nur eine Frage der Präferenz. Weitere Informationen dazu, wie sie sich unterscheiden, finden Sie in diesem offiziellen TypeScript-Dokumentations-Beispielbereich.
Definieren Sie als nächstes einen Unionstyp aus jedem Schlüssel in Ihrer Schnittstelle.
type MyFormDataKeys = keyof MyAllowedData
// das ist dasselbe wie `type MyFormDataKeys = 'id' | 'name' | 'age'`
Der keyof
-Operator hilft dabei, einen Unionstyp der Schlüssel eines Objekttyps zu erstellen, daher ist er sehr nützlich, wenn Sie keinen Unionstyp manuell für ein größeres Objekt mit vielen Schlüsseln definieren möchten.
Schritt 2: Erstellen Sie eine Hilfsfunktion zum Anhängen
Jetzt, da Sie Ihre streng typisierten Schlüssel definiert haben, ist der nächste Schritt, eine Hilfsfunktion zu erstellen, die sicherstellt, dass nur gültige Schlüssel an FormData angehängt werden.
function appendToFormData (formData: FormData, key: MyFormDataKeys, value: string) {
formData.append(key, value);
};
Die Funktion appendToFormData
nimmt drei Argumente entgegen. So funktioniert es:
-
Das erste Argument,
formData
, ist eine Instanz des FormData-Objekts. Hier werden Schlüssel/Wert-Paare angehängt, bevor sie in einer API-Anfrage gesendet werden. -
Das zweite Argument,
key
, ist der Schlüsselname des Feldes, das Sie anhängen möchten. Sein Typ istMyFormDataKeys
, der Unionstyp, den wir erstellt haben, um sicherzustellen, dass nur die von uns definierten Schlüssel an FormData angehängt werden. -
Das dritte Argument ist ein String
value
, der den Wert darstellt, der mit dem Schlüssel angehängt werden soll.
Beachten Sie, dass FormData akzeptiert nur die string
und Blob
Typen als Werte in jedem Schlüssel/Wert-Paar. In diesem Leitfaden arbeiten wir nur mit Zeichenfolgenwerten – aber denken Sie daran, dass Sie Blob-Werte verwenden können, um Dateien an API-Anfragen anzuhängen.
Jetzt wollen wir die Funktion testen:
const payload = new FormData();
appendToFormData(payload, "id", "19282"); // ✅ Erlaubt
appendToFormData(payload, "name", "Lenny Brown"); // ✅ Erlaubt
appendToFormData(payload, "age", "20"); // ✅ Erlaubt
appendToFormData(payload, "someOtherKey", "89"); // ❌ TypeScript Fehler: Argument des Typs 'someOtherKey' ist nicht zuweisbar.
Schritt 3: Verwenden Sie die Hilfsfunktion nach dem Absenden des Formulars
Jetzt fügen wir unsere Felder zu FormData hinzu, bevor wir sie an eine API senden.
const handleSubmitForm = () => {
const payload = new FormData();
appendToFormData(payload, "id", "19282");
appendToFormData(payload, "name", "Lenny Brown");
appendToFormData(payload, "age", "20");
// Payload über API senden
fetch("/api/submit", { method: "POST", body: payload });
};
Felder aus einem Objekt anhängen
Alternativ, wenn Sie bereits Ihren gesamten Payload in einem Objekt haben, können Sie das Anhängen jedes Feldes einzeln vermeiden, indem Sie die Funktion wie folgt implementieren:
const handleSubmitForm = () => {
// alle Ihre Felder in einem Objekt
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}`); // Verwenden Sie Template-Literale, um den Wert einzufügen
});
// Payload über API senden
fetch("/api/submit", { method: "POST", body: payload });
};
Im obigen Snippet verwenden wir Object.entries
, um über jedes Schlüssel/Wert-Paar in einem Objekt zu iterieren, damit es dem FormData-Objekt hinzugefügt werden kann. Beachten Sie, dass der Wert in jedem Paar, egal ob es sich um einen String oder eine Zahl handelt, als String über Template-Strings übergeben wird, um einen Typkonflikt in TypeScript mit dem value
-Argument in unserer Hilfsfunktion zu vermeiden.
Fazit
Durch die Nutzung des keyof
-Operators von TypeScript können wir FormData.append()
vollständig typsicher machen. Diese einfache Technik hilft, Schlüsselkonflikte zu vermeiden und macht Ihre API-Anfragen zuverlässiger.
Lassen Sie mich wissen, was Sie über den Artikel denken, und zögern Sie nicht, Vorschläge zu machen, von denen Sie glauben, dass sie meine Lösung verbessern könnten.
Danke fürs Lesen!
Source:
https://www.freecodecamp.org/news/how-to-enforce-type-safety-in-formdata-with-typescript/