Búsqueda de sitios web

javascript - Typescript infiriendo un valor definido como indefinido


Tengo el siguiente arreglo que puede ser un objeto o undefined. Incluso después de filtrar los resultados para que contengan todos los valores definidos, TypeScript todavía dice que podría ser undefined.

interface Bob {
    name: string;
}

type BobDetails = undefined | Bob;

const myArray: BobDetails[] = [{ name:  "Bob"}, undefined];
myArray[0].name; // expected Object is possibly 'undefined'.(2532)

var filter = myArray.filter(arr => arr?.name);
filter[0].name; // still Object is possibly 'undefined'.(2532)

¿Cómo hacer que Typescript sepa que filter[] tendrá solo Bob[] y ningún undefined? Soy consciente de que podríamos hacerlo con !, pero quiero que el flujo normal lo reconozca.

Ejemplo de Playground de Typescript

Respuesta #1

Para hacer eso, necesitas que tu función de filtro sea un guardián de tipo personalizado. En este momento, arr => arr?.name es solo una función que devuelve un string | undefined. Tú y yo podemos averiguar qué implicaciones tendrá eso para el arreglo resultante, pero TypeScript necesita un poco más.

Si cambias la función para que devuelva un booleano, y le das el tipo de retorno especial arr is Bob, entonces TypeScript sabe que si se devuelve true, entonces puede deducir que arr es un Bob. Y el método filter sabe que esto resultará en un Bob[]:

var filter = myArray.filter((arr): arr is Bob => arr?.name !== undefined);

Enlace del parque

Respuesta #2

Imagina que el arreglo es: BobDetails[]=[undefined, undefined];

Entonces filter[0].name; también será indefinido. Para mayor simplicidad, puedes comprobar la longitud de filter como:

if(filter.length>0){ filter[0].name; ... your code}