Following code works well, however I dont manage to type providesTags
correctly:
type Post = {
id: number,
name: string,
description: string,
}
const postsApiSlice = api.injectEndpoints({
endpoints: (builder) => ({
getPosts: builder.query<EntityState<Post>, void>({
query: ROUTES.POSTS,
transformResponse: (responseData: Post[]) => {
return adapter.setAll(initialState, responseData)
},
// Typescript error is here, at provideTags
providesTags: (result) => {
// What to do if result is undefined?
if (!result) return [{ type: POST_TAG, id: 'LIST' }]
const tags = (result.ids.length > 0) ?
// Typescript accepts type of next line if I return it
result.ids.map((id) => ({ type: POST_TAG, id }))
:
// Typescript also accepts type of next line if I return it
[{ type: POST_TAG, id: 'LIST' }]
return tags
}
}),
}),
})
Typescript error I get:
Type '(result: EntityState<Post> | undefined) => { type: string; id: EntityId; }[]' is not assignable to type 'ResultDescription<"Post", EntityState<Post>, void, FetchBaseQueryError, {} | undefined> | undefined'.
Type '(result: EntityState<Post> | undefined) => { type: string; id: EntityId; }[]' is not assignable to type 'GetResultDescriptionFn<"Post", EntityState<Post>, void, FetchBaseQueryError, {} | undefined>'.
Type '{ type: string; id: EntityId; }[]' is not assignable to type 'readonly TagDescription<"Post">[]'.
Type '{ type: string; id: EntityId; }' is not assignable to type 'TagDescription<"Post">'.
Type '{ type: string; id: EntityId; }' is not assignable to type 'FullTagDescription<"Post">'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"Post"'.ts(2322)
endpointDefinitions.d.ts(188, 5): The expected type comes from property 'providesTags' which is declared here on type 'Omit<EndpointDefinitionWithQuery<void, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, {}>, EntityState<Post>> & { ...; } & { ...; } & QueryExtraOptions<...>, "type"> | Omit<...>'
If I return just result.ids.map((id) => ({ type: POST_TAG, id }))
or just [{ type: POST_TAG, id: 'LIST' }]
works correctly.
- How can I type it?
- Also, not sure what should I do when result is
undefined
. Should I return[{ type: POST_TAG, id: 'LIST' }]
?
CodePudding user response:
This is described in typing providesTag/invalidatesTags.
You will need a few as const
assertions when you define POST_TAG
.
So not const POST_TAG = "foo"
, but const POST_TAG = "foo" as const
should do the trick. Otherwise it will be typed as "string", not as "foo".