Tengo un tipo que es:
export enum ApiFunctions { "setHidden" = "HIDE", "setReadOnly" = "SET_READ_ONLY", "setDescription" = "DESCRIPTION" } export type ValueOfApiFunction = `${ApiFunctions}`y la lógica que está escuchando un evento en la ventana así
window.addEventListener("message", (event) => { if(event.data.type === "COMPLETE") { event.data.changes.forEach((change: { fieldId: string, action: ValueOfApiFunction }) => { const field = api.getFieldById(change.fieldId); //I want to make sure that within this forEach all values of the type above are covered and if not, through a compilation error // in this case "DESCRIPTION" isn't included so I would want a compilation error being thrown if(change.action === "HIDE") { field?.setVisible(false); } else if(change.action === "SET_READ_ONLY") { field?.setName("This field is now read only") } }) resolve(); } if(event.data.type === "MAKE_REQUEST") { invoke('makeRequest', { url: event.data.url }).then(result => { console.log(result); iframe.contentWindow?.postMessage({ type: "REQUEST_COMPLETE", response: result }, "*") }); } })He explicado lo que quiero lograr en un comentario en el bloque de código anterior, pero básicamente quiero asegurarme de que todos los valores de mi tipo estén cubiertos dentro de la lógica forEach, si no, error de compilación.
Muchas gracias
Puede aprovechar el tipo 'nunca' de esta manera:
event.data.changes.forEach((change: { fieldId: string, action: ValueOfApiFunction }) => { const field = api.getFieldById(change.fieldId); if(change.action === "HIDE") { field?.setVisible(false); } else if(change.action === "SET_READ_ONLY") { field?.setName("This field is now read only") } else { const _shouldNeverBeReached: never = change.action } }) Ahora, si olvida manejar una change.action de cambio, el tipo no será nunca y, por lo tanto, no se compilará.
ACTUALIZACIÓN: para un mensaje más explícito:
const exaustiveCheck = <T extends any>(t: T extends never ? never : "One of the cases was not handled") => { throw new Error("One of the cases was not handled") }y entonces
} else { exaustiveCheck(change.action) }TypeScript no tiene una capacidad nativa para imponer el uso de cierta lógica dentro de una base de código. Se preocupa principalmente de que los objetos no se manipulen incorrectamente, en lugar de inspeccionar lo que está haciendo el código correcto. Sin embargo, existe una solución alternativa que le permitiría asegurarse de que la lógica se ejecute para cada posibilidad de una enumeración:
Puede crear un objeto JSON que contenga todos los valores de enumeración como sus claves, y cada clave tiene un valor de una función, lo que significa que se ejecuta una parte de la lógica para cada enumeración de la siguiente manera:
const fieldToAction: { [key in ValueOfApiFunction]: (field?: Field) => void } = { "HIDE": (field?: Field) => field?.setVisible(false), "SET_READ_ONLY": (field?: Field) => field?.setName("This field is now read only"), "DESCRIPTION": (field?: Field) => field?.setName("This field is now read only"), } (El tipo Field podría ser algo diferente ya que no se proporcionó en el ejemplo)
Todo lo que necesita hacer ahora es llamar a esto dentro de su forEach de la siguiente manera:
fieldToAction[change.action](field);El enlace de Playground que ilustra este comportamiento se puede encontrar aquí .