reactjs - redux-toolkit'te provideTags nasıl yazılır (çok öğeli uç nokta)


Aşağıdaki kod iyi çalışıyor, ancak providesTags öğesini doğru şekilde yazmayı başaramıyorum:

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
        }
      }),
    }),
  })

Aldığım Typescript hatası:

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<...>'

Eğer sadece result.ids.map((id) => ({ type: POST_TAG, id })) veya sadece [{ type: POST_TAG, id: 'LIST' }] dönersem düzgün çalışıyor.

  • Bunu nasıl yazabilirim?
  • Ayrıca, sonuç undefined olduğunda ne yapmam gerektiğinden emin değilim. [{ type: POST_TAG, id: 'LIST' }] döndürmeli miyim?

Cevap #1

Bu, typing providesTag/invalidatesTags içinde açıklanmıştır.

POST_TAG'i tanımlarken birkaç as const bildirimi yapmanız gerekecek.

Yani const POST_TAG="foo" değil, const POST_TAG="foo" as const işe yarayacaktır. Aksi takdirde "foo" olarak değil, "string" olarak türlendirilir.