redux 尝试下载文件,在使用baseQueryWithReauth时丢失queryFn中responseHandler中的返回值类型

laawzig2  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(121)

我正在尝试下载一个文件,使用一个突变端点,它 Package 了一个queryFn。突变的代码看起来像:

downloadTournamentTRF: builder.mutation<{filename: string}, {id: Tournament["id"]}>({
    queryFn: async ({id}, api, extraOptions, baseQuery) => {
        return baseQuery({
            url: `/tournament/trf/${id}`,
            responseHandler: async (response) => {
                if (response.ok) {
                    const filename = await saveResponseUsingHiddenElement(response);
                    return {data: {filename}};
                } else {
                    return {error: {status: response.status, message: response.statusText}};
                }
            },
            cache: "no-cache"
        });
    }
}),

这会在queryFn类型上产生错误:

TS2322: Type '({ id }: { id: number; }, api: BaseQueryApi, extraOptions: {}, baseQuery: (arg: string | FetchArgs) => MaybePromise<QueryReturnValue<unknown, FetchBaseQueryError, {}>>) => Promise<...>' is not assignable to type '(arg: { id: number; }, api: BaseQueryApi, extraOptions: {}, baseQuery: (arg: string | FetchArgs) => MaybePromise<QueryReturnValue<unknown, FetchBaseQueryError, {}>>) => MaybePromise<...>’.
   Type 'Promise<QueryReturnValue<unknown, FetchBaseQueryError, {}>>' is not assignable to type 'MaybePromise<QueryReturnValue<{ filename: string; }, FetchBaseQueryError, unknown>>’.
     Type 'Promise<QueryReturnValue<unknown, FetchBaseQueryError, {}>>' is not assignable to type 'PromiseLike<QueryReturnValue<{ filename: string; }, FetchBaseQueryError, unknown>>’.
       Types of property 'then' are incompatible.
         Type '<TResult1 = QueryReturnValue<unknown, FetchBaseQueryError, {}>, TResult2 = never>(onfulfilled?: ((value: QueryReturnValue<unknown, FetchBaseQueryError, {}>) => TResult1 | PromiseLike<...>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | ... 1 more ... | undefined) => Promise<...>' is not assignable to type '<TResult1 = QueryReturnValue<{ filename: string; }, FetchBaseQueryError, unknown>, TResult2 = never>(onfulfilled?: ((value: QueryReturnValue<{ filename: string; }, FetchBaseQueryError, unknown>) => TResult1 | PromiseLike<...>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | ... 1 mo...’.
           Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
             Types of parameters 'value' and 'value' are incompatible.
               Type 'QueryReturnValue<unknown, FetchBaseQueryError, {}>' is not assignable to type 'QueryReturnValue<{ filename: string; }, FetchBaseQueryError, unknown>’.
                 Type '{ error?: undefined; data: unknown; meta?: {} | undefined; }' is not assignable to type 'QueryReturnValue<{ filename: string; }, FetchBaseQueryError, unknown>’.
                   Type '{ error?: undefined; data: unknown; meta?: {} | undefined; }' is not assignable to type '{ error?: undefined; data: { filename: string; }; meta?: unknown; }’.
                     Types of property 'data' are incompatible.
                       Type 'unknown' is not assignable to type '{ filename: string; }’.

在我们的baseQuery中,我们使用了一个baseQueryWithReauth函数,该函数基于本文文档中的代码。我们的代码实际上没有改变,看起来如下:

const baseQueryWithReauth: BaseQueryFn<string | FetchArgs,
    unknown,
    FetchBaseQueryError> = async (args, api, extraOptions) => {
    [...]
};

问题似乎是BaseQueryFn泛型的第二个类型参数设置为unknown,这似乎抑制了导致错误的返回类型。
是否有方法可以更改类型定义以保留返回类型并清除错误?
谢谢你!

fruv7luv

fruv7luv1#

baseQuery将始终返回unknown-它从服务器获取数据,但无法知道它是什么。如果您是程序员,则可以始终执行as Something-或者您可以编写自定义Assert函数或使用类似zod的函数来解析和验证返回类型。
再看一下,你做得有点过头了--queryFn需要返回{data}{error}形状的对象,但transformResponse不需要,而且看起来你根本不需要queryFn
这应该做到:

export const chessMasterApi = createApi({
  reducerPath: 'chessMasterApi',
  baseQuery: baseQueryWithReauth,
  tagTypes: ['Audit'],
  endpoints: (builder) => ({
    downloadTournamentTRF: builder.mutation<
      { filename: string },
      { id: Tournament['id'] }
    >({
      query: ({ id }) => ({
        url: `/tournament/trf/${id}`,
        responseHandler: async (response) => {
          return await saveResponseUsingHiddenElement(response);
        },
        cache: 'no-cache',
      }),
    }),
  }),
});
hivapdat

hivapdat2#

这真的很棒,工作得很好--谢谢你的帮助!
我必须做的一个更改是让它正确处理错误:

export const chessMasterApi = createApi({
  reducerPath: 'chessMasterApi',
  baseQuery: baseQueryWithReauth,
  tagTypes: ['Audit'],
  endpoints: (builder) => ({
    downloadTournamentTRF: builder.mutation<
      { filename: string },
      { id: Tournament['id'] }
    >({
      query: ({ id }) => ({
        url: `/tournament/trf/${id}`,
        responseHandler: async (response) => {
          if (response.ok) {
            return await saveResponseUsingHiddenElement(response);
          } else {
            return {message: response.statusText};
        },
        cache: 'no-cache',
      }),
    }),
  }),
});

相关问题