I'm making a program using React for the UI development. The program is meant to access the file system for settings so I run some server code in node and use RTK query to do the communication with that code.
Some of the server code reads a value from an xml file. I have these interfaces defined in the server code that define the type of the request and response parameters:
// define the key and value pairing for the file
export interface PersistentFileValues {
initialValue: number;
repaymentChanges: DatedValue[];
}
// queries should provide a key that matches the pairing
export interface GetPersistentFileValueRequestQuery {
itemKey: keyof PersistentFileValues;
}
// define type that gets the value type given a key
export type PersistentFileValue<T extends keyof PersistentFileValues> =
PersistentFileValues[T];
// make GetPersistentFileValueResponseBody depend on GetPersistentFileValueRequestQuery
export interface GetPersistentFileValueResponseBody<
T extends GetPersistentFileValueRequestQuery
> {
value: PersistentFileValue<T['itemKey']>;
}
If I use createApi, and have an endpoint called getPersistentFileValue, how do I do the typing so that the hooks figure out the return type based on the key provided as an argument?
Currently I have:
endpoints: (builder) => ({
getPersistentFileValue: builder.query<
PersistentFileValue<keyof PersistentFileValues>,
GetPersistentFileValueRequestQuery
>({
query: (queryData) => {
return {
url: constructGetPersistentFileValueUrl(queryData), // appends the data as a string to the url
method: 'get',
};
},
transformResponse: (result, _meta, arg) => {
const out = result as GetPersistentFileValueResponseBody<typeof arg>;
return out.value;
},
}),
...
There don't seem to be any type errors. However, when I use the hook:
const { data: repaymentChanges } = useGetPersistentFileValueQuery({
itemKey: 'repaymentChanges',
});
I find that the type of repaymentChanges is too generic and I get an error if I try to get the length property.
How can I type things so that the hooks give me access to the data with the right type? Is there a better way to do this?
Before this I was making an endpoint for each value accessed from the file, but that seems pretty clunky.
CodePudding user response:
As RTK Query is mapping types internally to create those new function signatures, any kind of generics/overloads will be getting lost. Your best bet is taking the RTK Query-generated hook, wrapping it in your own function and providing overloads for that.