es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Tipo de guardia para verificar que cada elemento de un arreglo esté definido

Estaba preguntándome si es posible crear un guardia de tipo que verifique si cada elemento de un array está definido. Ya tengo un guardia de tipo para verificar un único valor, pero tener una solución que haga eso para todo el array (sería genial).

Para ponerlo en código, estoy buscando algo que haga guardia de tipo en lo siguiente:

// Tipo de array de entrada:
[ Something | undefined, SomethingDifferent | undefined ]

// Guardia de tipo resolviendo a:
[ Something, SomethingDifferent ]

Actualmente tengo el siguiente guardia de tipo para verificar un único elemento:

function isDefined<t>(value: T | undefined | null): value is T {
    return value !== null && typeof value !== 'undefined';
}

La implementación lógica del guardia de tipo es bastante fácil (especialmente cuando se reutiliza para un único valor):

function isEachItemDefined<t extends=""></t><unknown>>(value: T): ?? {
    return value.every(isDefined);
}

Mi caso de uso para esto sería filtrar después de usar el operador withLatestFrom (RxJS). Tengo un caso especial en el que me gustaría filtrar el “evento” siempre que alguno de los valores no esté definido.

typescript
observable1.pipe(
withLatestFrom(observable2, observable3, observable4), // <-- cada uno devuelve un valor o undefined
filter(isEachItemDefined),
map(([ item1, item2, item3, item4 ]) => {
// incluso si la lógica funciona correctamente,
// typescript no reconocería los elementos como definidos
// por ejemplo, item2 seguiría siendo "string | undefined"
}),
);

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible crear una guardia de tipos que compruebe si cada elemento de un array está definido. La implementación sería la siguiente:

    function isEachItemDefined<t>(value: (T | undefined)[]): value is T[] {
        return value.every(isDefined);
    }
    

    Esta guardia de tipos recibe un array de tipo (T | undefined)[] y devuelve true si cada elemento en el array está definido, es decir, no es undefined. La función isDefined() se reutiliza dentro de la función isEachItemDefined() y se pasa al método Array.prototype.every() para comprobar cada elemento.

    En tu caso de uso, puedes utilizar esta guardia de tipos para filtrar cualquier evento en el que algún valor no esté definido, como se muestra a continuación:

    observable1.pipe(
        withLatestFrom(observable2, observable3, observable4),
        filter(isEachItemDefined),
        map(([ item1, item2, item3, item4 ]) => {
            // item1, item2, item3 y item4 ahora son de tipo T,
            // donde T es el tipo de los valores no undefined en el array de entrada
        }),
    );
    

    Con esta implementación, TypeScript debería inferir correctamente los tipos de los elementos no undefined en el array, es decir, item1 es de tipo T y no T | undefined.

Comments are closed.