javascript - vue-apollo - Η ιδιότητα 'value' δεν υπάρχει στον τύπο 'Readonly>>'


Η ΚΑΤΑΣΤΑΣΗ:

Προσπαθώ να ενσωματώσω το vue-apollo v4 με Typescript.

Ανάκτω ένα απλό ερώτημα χρησιμοποιώντας το useQuery και το useResult.

Το useResult από προεπιλογή επιστρέφει αυτόν τον τύπο: Readonly<Ref<Readonly<any>>>

Ο ΚΩΔΙΚΑΣ:

import { GET_COUNTRY } from '../graphql/queries'
import { Country } from '../types'

setup() {
  const route = useRoute()
  const code = route.params.code

  const { result, loading } = useQuery(GET_COUNTRY, {code: code}, { 
    clientId: 'default', 
    fetchPolicy: 'cache-first'
  });
  const country = useResult(result, {}, (data) => data.country);

  console.log(country.name) // Property 'name' does not exist on type 'Readonly<Ref<Readonly<any>>>'.ts(2339)

  return {
    country,
    loading
  }
}

ΠΡΟΣΠΑΘΕΙΑ 1:

const country: Country = useResult(result, {}, (data) => data.country);
// Type 'Readonly<Ref<Readonly<any>>>' is missing the following properties from type 'Country': native, phone, capital, currency, and 6 more.ts(2740)

ΠΡΟΣΠΑΘΕΙΑ 2:

const country = useResult(result, {}, (data) => data.country as Country);
console.log(country.name) // Property 'name' does not exist on type 'Readonly<Ref<Readonly<any>>>'.ts(2339)

ΠΡΟΣΠΑΘΕΙΑ 3:

const country: Country = useResult(result, {}, (data) => data.country as Country);
// Type 'Readonly<Ref<Readonly<Country | {}>>>' is missing the following properties from type 'Country': native, phone, capital, currency, and 6 more.ts(2740)

ΠΡΟΣΠΑΘΕΙΑ 4:
Μετά τα σχόλια από τον @tony19

const { result, loading } = useQuery<Country>(GET_COUNTRY, {code: code});
const country = useResult(result, {}, (data) => data.country);
// Property 'country' does not exist on type '{ native: string; phone: string; capital: string; currency: string...

ΠΡΟΣΠΑΘΕΙΑ 5:
Μετά την επεξεργασμένη απάντηση από τον @tony19

// QUERY - simplified
export const GET_COUNTRY = gql`
  query getCountry($code: ID!) {
    country(code: $code) {
      code
      name
    }
  }
`
// TYPES - simplified
export interface Country {
  code: string,
  name: string
}

export type CountryQuery = {
  country: Country
}
const { result, loading } = useQuery<CountryQuery>(GET_COUNTRY, {code: code});
const country = useResult(result, {}, (data) => data.country);

Λαμβάνω την ακόλουθη προειδοποίηση στο vsCode:

 Property 'name' does not exist on type 'Readonly<{}>'.

ΠΡΟΣΠΑΘΕΙΑ 5b:
Αν, όπως στην απάντηση του @tony19, κάνω τον παρακάτω τύπο:

type CountryQuery = {
  getCountry: Country
}

Τότε παίρνω αυτό το σφάλμα:

Property 'country' does not exist on type '{ getCountry: { code: string; name: string; }; }'

Η ΕΡΩΤΗΣΗ:

Είναι δυνατόν να συνδυάσω το useResult με το δικό μου Typescript interface;

Απάντηση #1

Υποθέτοντας τους ακόλουθους τύπους:

type Country = {
  name: string
}

const GET_COUNTRY = gql`
  query GetCountry {
    getCountry {
      name
    }
  }
`

Το αποτέλεσμα θα πρέπει να πληκτρολογηθεί ώστε να ταιριάζει με το ερώτημα GET_COUNTRY παραπάνω:

type CountryQuery = {
  getCountry: Country
}

Στη συνέχεια, καθορίστε αυτόν τον τύπο ερωτήματος ως όρισμα τύπου στο useQuery():

const { result, loading } = useQuery<CountryQuery>(GET_COUNTRY, ⋯)
                                        👆

Τώρα, το όρισμα data της συνάρτησης ανάκλησης useResult() είναι τύπου CountryQuery, οπότε χρησιμοποιήστε data.getCountry.name για να πάρετε το όνομα της χώρας:

                                        👇 type is CountryQuery
const country = useResult(result, {}, (data) => data.getCountry.name);
                                                        👆

result και country είναι ref αντικείμενα, οπότε για να αποκτήσετε πρόσβαση στα υποκείμενα δεδομένα, ξετυλίξτε τα με .value:

console.log(country.value);
                      👆

ντίμο