javascript - Vue-router cu Typescript și guard beforeEnter, cum se folosesc datele validate?


Folosesc Vue și vue-router cu TypeScript, am un caz comun al unei singure pagini pentru un component Photo care să fie afișat, am o rută cu un `beforeEnter` guard care interoghează magazinul meu pentru a vedea dacă fotografia cerută există de fapt

    {
        name: 'photo',
        path: '/photos/:id',
        meta: {requiresAuth: true},
        component: () => import('@/pages/Photo.vue'),
        beforeEnter: (to, from, next) => {
            const photos = usePhotos();
            const requestedPhoto = photos.$state.photos.findIndex(p => p.uuid === to.params.id)
            return requestedPhoto === -1 ? next({name: 'home'}) : next()
        },
    }

În exemplul meu, verific deja în beforeEnter dacă fotografia solicitată există, acum, dacă totul merge bine, utilizatorul ajunge în componentă.

În componenta mea preiau din nou fotografia din magazin folosind următoarea linie de cod

const photo = photoStore.photos.find(p => p.uuid === route.params.id)

Acum TS îmi va spune că această fotografie ar putea fi nedefinită, deoarece operațiunea find s-ar putea să nu returneze niciun rezultat, totuși știm deja din pasul de verificare că această fotografie va fi într-adevăr găsită.

const photo = photoStore.photos.find(p => p.uuid === route.params.id)
const uuid = photo!.uuid

Aș putea folosi afirmația non-null din TypeScript, dar ESLint nu o acceptă, îmi spune: ESLint: Afirmație non-null interzisă.(@typescript-eslint/no-non-null-assertion)

Așadar, mă întreb, care este cea mai bună practică pentru a gestiona o situație ca aceasta?

Răspuns #1

Dacă photo este garantat că există, acesta este cazul pentru operatorul de aserțiune non-null. Regulile ESLint pot fi dezactivate temporar deoarece nu servesc un scop bun aici.

Dacă photo nu este garantat că există, este incorect să folosești operatorul de aserțiune non-null deoarece acest lucru poate duce la o eroare la rulare. Acesta este cazul pentru protecția tipului:

const photo = photoStore.photos.find(p => p.uuid === route.params.id)

if (photo) {
  const uuid = photo.uuid // undefined excluded from photo type
  ...
} else {
  ....
}