Quando si lavora con l’interfaccia FormData in JavaScript, dove i dati vengono aggiunti come coppie chiave/valore, non c’è un modo incorporato per garantire la sicurezza dei tipi sulle chiavi che si aggiungono. Ciò può portare a errori di battitura, chiavi mancanti e errori imprevisti durante l’esecuzione. Ma in TypeScript, possiamo risolvere questo problema imponendo una rigorosa validazione delle chiavi.

Ho avuto bisogno di questa soluzione io stesso quando inviavo i valori del mio modulo a un’API. In seguito ho realizzato di aver commesso diversi errori di battitura in più di una coppia chiave/valore che stavo cercando di aggiungere al mio payload. Poiché FormData accetta qualsiasi stringa come chiave, ero in grado di passare le stringhe sbagliate e procedere con la richiesta API.

Dopo che questo è successo, ho cercato un modo per assicurarmi che TypeScript non consenta quegli errori.

Questo articolo ti mostrerà come rendere le chiavi di FormData sicure dal punto di vista dei tipi utilizzando TypeScript.

Prerequisiti

Per trarre il massimo da questo articolo, dovresti avere una conoscenza di base dei seguenti aspetti:

  1. programmazione JavaScript

  2. i fondamenti di TypeScript, in particolare come funzionano le interfacce, i tipi e l’operatore keyof

  3. l’interfaccia FormData

Se sei nuovo di TypeScript o FormData, ti consiglio di dare un’occhiata alla documentazione ufficiale di TypeScript e alla guida su FormData di MDN prima di procedere.

Passo 1: Definisci le tue Chiavi Consentite

Il Vecchio Modo

Il modo predefinito per aggiungere dati con FormData è farlo manualmente, con semplici stringhe:

const payload = new FormData();

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

payload.append("agge", "36"); // Un errore nella chiave è consentito

Nel codice sopra, puoi vedere che c’è stato un errore di battitura quando si definiva una chiave per age. Ma TypeScript non lo segnalerà come un errore, e questo potrebbe causare problemi quando questi dati vengono inviati con una richiesta API.

Il Modo Migliore

Invece di digitare manualmente le chiavi, definiscile in uno schema di oggetti con un’interfaccia TypeScript.

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

In alternativa, puoi definirle con tipi:

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

Puoi usare tipi o interfacce, è solo una questione di preferenza. Puoi scoprire di più su come differiscono in questo playground della documentazione ufficiale di TypeScript.

Successivamente, definisci un tipo unione da ogni chiave nella tua interfaccia.

type MyFormDataKeys = keyof MyAllowedData
// questo è lo stesso come `type MyFormDataKeys = 'id' | 'name' | 'age'`

L’operatore keyof aiuta a creare un tipo di unione delle chiavi di un tipo di oggetto, quindi è davvero utile se non si vuole definire manualmente un tipo di unione per un oggetto più grande con molte chiavi.

Passo 2: Creare una funzione di supporto per l’aggiunta

Ora che hai definito le chiavi strettamente tipizzate, il passo successivo è creare una funzione di supporto che garantisca che solo le chiavi valide vengano aggiunte a FormData.

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

La funzione appendToFormData prende in input tre argomenti. Ecco come funziona tutto:

  • Il primo argomento, formData, è un’istanza dell’oggetto FormData. Qui verranno aggiunte coppie chiave/valore prima di inviarle in una richiesta API.

  • Il secondo argomento, key, è il nome della chiave del campo che si desidera aggiungere. Il suo tipo è MyFormDataKeys, il tipo di unione che abbiamo creato per garantire che solo quelle chiavi che abbiamo definito vengano aggiunte a FormData.

  • Il terzo argomento è una stringa value che rappresenta il valore da aggiungere con la chiave.

Nota che FormData accetta solo i string e Blob come valori in ciascuna coppia chiave/valore. In questa guida, stiamo lavorando solo con valori di stringa – ma tieni presente che puoi utilizzare valori di blob per aggiungere file alle richieste API.

Ora, testiamo la funzione:

const payload = new FormData();

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

appendToFormData(payload, "someOtherKey", "89"); // ❌ Errore TypeScript: L'argomento di tipo 'someOtherKey' non è assegnabile.

Passo 3: Utilizza la funzione di aiuto dopo l’invio del modulo

Ora aggiungiamo i nostri campi a FormData prima di inviarli a un’API.

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

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

Aggiunta dei campi da un oggetto

In alternativa, se hai già l’intero payload in un oggetto, puoi evitare di aggiungere ogni campo uno per uno implementando la funzione in questo modo:

const handleSubmitForm = () => {
  // tutti i tuoi campi in un oggetto
  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}`); // usa i template letterali per passare il valore
  });

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

Nello snippet sopra, stiamo utilizzando Object.entries per iterare su ogni coppia chiave/valore in un oggetto in modo che possa essere aggiunto all’oggetto FormData. Nota che il valore in ogni coppia, che sia una stringa o un numero, viene passato come stringa utilizzando i template letterali per evitare un mismatch di tipo TypeScript dall’argomento value nella nostra funzione di supporto.

Conclusione

Sfruttando l’operatore keyof di TypeScript, possiamo rendere FormData.append() completamente sicuro dal punto di vista dei tipi. Questa semplice tecnica aiuta a prevenire mismatch delle chiavi e rende le richieste API più affidabili.

Fammi sapere cosa ne pensi dell’articolo e sentiti libero di fare suggerimenti che ritieni possano migliorare la mia soluzione.

Grazie per la lettura!