Bonjour à tous,

Je vais essayé d'être le plus claire possible. Je développe une App iOS/Android avec React Native et Type Script.
En partant de zéro, j'ai tout appris avec le Web et Youtube.

Grâce à un tuto, j'ai pu faire une fonction (solution 1) qui va faire appelle à useQuery pour extraire les données d'un base de donnée, le tout typé.
J'utilise cette fonction sur trois vues. Ces trois font appelle à cette fonction et le paramètre queryKey est le même pour ces trois vues

Pour un besoin, j'utilise réutilisé directement la fonction useQuery() (solutiuon 2)pour que je puisse paramètre queryKey pour une vue.
Mon problème est que je n'ai pas réussi à typer ma sortie....

Pour être plus précis, je vous montre la solution 1, afin de mieux comprendre ma question

Dans ma vue setting.tsx, j'ai ceci

Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
import { useFetchQuery } from "@/hooks/useFetchQuery";
const {data, isFetching} = useFetchQuery("/getsettings/[id_field]/[id_user]", {id_field: 0, id_user:id_user})

Dans mon fichier useFetchQuety.ts, j'ai ceci

Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
 
const endpoint = "https://api.web.ch/dashboard"
 
type API = {
'/getsettings/[id_field]/[id_user]': {
        response: number, 
        id_field: number,
        method: string,
        fields:{
            id_field: number,
            field_name: string,
            field_longname: string,
            field_city: string,
            field_lat: number,
            field_lng: number
        }[],
        settings: {
            id_station_type?: number,
            station_type_name: string,
            station_type_awe?: string,
            field_data: {
                id_field: number,
                field_name: string,
                field_user_role: number,
                station_data: {
                    id_station: number,
                    station_name: string,
                    station_longname: string,
                    station_type_awe: string,
                    station_archive: number,
                    station_lat: number,
                    station_lng: number,
                    station_alt: number,
                    sensors_data: {
                        id_sensor: number,
                        sensor_active: number,
                        sensor_name: string,
                        sensor_unit: string,
                        sensor_longname: string,
                        id_sensor_type: number,
                        sensor_type_name: string,
                        sensor_type_longname: string,
                        sensor_type_awe: string,
                        sensor_chart_style: string,
                        sensor_chart_borderWidth: string,
                        sensor_chart_pointRadius: number,
                        sensor_chart_showLine: number,
                        sensor_chart_fill: number,
                        sensor_chart_borderColor: string,
                        sensor_chart_backgroundColor: string,
                        sensor_chart_pointStyle: string,
                        sensor_threshold_operator:'string',
                        sensor_threshold_min: number,
                        sensor_threshold_max: number,
 
                    }[],
                }[],
            }[],
        }[],
    }
}
 
export function useFetchQuery<T extends keyof API>(path: T, params?: Record<string, string | number>){
    const localurl = endpoint + Object.entries(params ?? {}).reduce((acc, [key, value]) => acc.replaceAll(`[${key}]`, value.toString()) as T, path)
 
    //console.log("useFetchUqrey: ",localurl)
 
    return useQuery({
        queryKey: [localurl],
        //refetchIntervalInBackground: true,  
        //refetchInterval: 60000, // 60 000 ms = 60 secondes
        //refetchOnWindowFocus: false,
        //staleTime:30000,
        queryFn: async () => { // Comment on reécupère les résultat
            //await wait(2);
            return fetch(localurl,{
                headers:{
                    Accept: 'application/json',
                }
            }).then((r) => r.json() as Promise<API[T]>); // Convertir le résultat (r) en json
        },
    })
}

Le mega avantage, est que
Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
const {data, isFetching} = useFetchQuery("/getsettings/[id_field]/[id_user]", {id_field: 0, id_user:id_user})

lorsque je saisi data. , après le point il me propose toutes les possiblités qui sont défini dans API.

Solution 2
Dans la solution 2, je le fais différemment. Dans ma vue [id].tsx, j'ai

Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
const {data, isPaused, isLoading, error, refetch, isFetching}= useQuery({ // Min 52 https://www.youtube.com/watch?v=bpHq_-bPkGo
        queryKey: ['station', params.id, dateRange],
        queryFn: () => fetchStation(params.id, dayjs(dateRange.startDate).format("YYYY-MM-DD"), dayjs(dateRange.endDate).format("YYYY-MM-DD"), id_user),
        //retryOnMount: false,
        refetchInterval: 30000,
        //gcTime: 1000 * 60,
        //staleTime: 1000 * 30, // Data remains fresh for 60 sec
        refetchOnWindowFocus: true,
        //enabled: false,
        //retry: 2, // Retry twice on failure
        //retryDelay: 2000, // Wait 2 seconds between retries
        //select: (data) => data.map((post) => post.title), // Extract only post title
    })
Comme vous pouvez le voir, je peux directement paramètrer useQuery.

Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
import { QueryClient, useInfiniteQuery, useQuery } from '@tanstack/react-query'
 
const uri = "https://api.web.ch/dashboard"
const endpoint = "/getstation/"
const params = "/"
 
const headers = {
    accept: 'application/json',
    Authorisation: 'key',
}
 
export const fetchStation = async (id:string, dateFrom:string, dateTo:string, user_id:number) => {
 
    const url = uri+endpoint+id+'/'+dateFrom+'/'+dateTo+'/'+user_id+'/';
    const options = {
        method: 'GET',
        headers,
    };
 
    try {
        const res = await fetch(url, options);
        /*
        if(!res.ok){
           throw new Error('[fetchQuery] Failed to fetch a s tation') 
        }
        */
        const json = await res.json();
        return json;
 
    }catch(err){
        console.error('[fetchQuery] ' + err);
    }
 
};
queryFn fait appelle à la fonction fetchStation() qui va s'occuper de faire la requête sur ma base de données.

cela fonctionne très bien, sauf que, ... dans la solution deux, je n'ai pas de typage. Docn si je fais

data. , après le point j'ai pas d'option. Tout cela, parce que je n'ai pas comme dans la solution 1, le API, genre

Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 
type API = {
'/getsettings/[id_field]/[id_user]': {
        response: number, 
        id_field: number,
        method: string,
        fields:{
            id_field: number,
            field_name: string,
            field_longname: string,
            field_city: string,
            field_lat: number,
            field_lng: number
        }[],
        settings: {
            id_station_type?: number,
            station_type_name: string,
            station_type_awe?: string,
            field_data: {
                id_field: number,
                field_name: string,
                field_user_role: number,
                station_data: {
                    id_station: number,
                    station_name: string,
                    station_longname: string,
                    station_type_awe: string,
                    station_archive: number,
                    station_lat: number,
                    station_lng: number,
                    station_alt: number,
                    sensors_data: {
                        id_sensor: number,
                        sensor_active: number,
                        sensor_name: string,
                        sensor_unit: string,
                        sensor_longname: string,
                        id_sensor_type: number,
                        sensor_type_name: string,
                        sensor_type_longname: string,
                        sensor_type_awe: string,
                        sensor_chart_style: string,
                        sensor_chart_borderWidth: string,
                        sensor_chart_pointRadius: number,
                        sensor_chart_showLine: number,
                        sensor_chart_fill: number,
                        sensor_chart_borderColor: string,
                        sensor_chart_backgroundColor: string,
                        sensor_chart_pointStyle: string,
                        sensor_threshold_operator:'string',
                        sensor_threshold_min: number,
                        sensor_threshold_max: number,
 
                    }[],
                }[],
            }[],
        }[],
    }
}

ma question


J'ai aucune idée, comment je peux adapter la solution 2, pour appliquer le typage, comme dans la solution 1, de manière simple.
La solution 1, je l'ai écris en suivant un tuto, et ca me semble complique

Auriez-vous la gentillesse de me guider et m'aider à modifier/adapter la solution 2 pour ajouter le typage?

je vous remercie et je vous souhaite uen bonne année