vendredi 2 septembre 2022

What tools/pattern are useful to create an interface that can be made dynamically reusable with generics?

I have an object like this, and I plan to keep this as a template that takes an arbitrary number of fields. I want to design an interface such that i can supply an array of field names and that it can be slotted into this object as suggested below. but im not sure if im doing it correctly, or over complicating it.

   let formResponse: FormResponsePayload<["email", "username"]> = {
      status: 'ERROR',
      fieldsWithError: ['email', 'username'], //empty or filled with the fields corresponding to keys of fields
      fields: {
        email: {
          field_name: 'email',
          status: 'error',
          message: ''
        },
        username: {
          field_name: 'email',
          status: 'error',
          message: ''
        }
      }
    }

the answer I've come up with

//i was looking for something that could unpack my generic of string[]. i found Unpacked on another Stack answer. not totally sure how it works.
type Unpacked<T> = T extends (infer U)[] ? U : T;


interface CheckField<A extends string> {
    field_name: A,
    status: string, 
    message: string
}

export interface FormResponsePayload<A extends string[]> {
    status: 'ERROR' | 'SUCCESS'
    fieldsWithError: Unpacked<A>[],
    fields: {
        [key in Unpacked<A>]: CheckField<Unpacked<A>>
    }
}

Aucun commentaire:

Enregistrer un commentaire