在 Thunk 中间件中引入额外参数时出现 Redux Toolkit 打字稿错误

Redux Toolkit typescript error when inyecting extra argument in Thunk Middleware

提问人:Ale 提问时间:11/16/2023 更新时间:11/16/2023 访问量:37

问:

我正在尝试自定义 Redux 工具包包含的中间件以添加额外的参数。 这个额外的参数是 Repository 的实现。

当我配置存储时,我添加了额外的参数:

export const store = configureStore({
 reducer: {
  students: students,
 },
 middleware: (getDefaultMiddleware) =>
  getDefaultMiddleware({
   thunk: {
    extraArgument: createAPIStudentRepository,
  },
  serializableCheck: false,
 }),
});

createAPIStudentRepository类型为:StudentRepository

export const createAPIStudentRepository = (): StudentRepository => {
 return {
   loadStudents: async (query: string, page: number, limit: number) => {
     const response = await fetch(API_STUDENTS_URL(query, page, limit));
     const results = (await response.json()) as Student[];
     return results;
  },
 };
};

这是存储库:Student

export interface StudentRepository {
 loadAStudents(
   query: string,
   page: number,
   limit: number
 ): Promise<Student[]>;
}

然后,在我的 Redux Thunk 中,我想使用我在配置存储时注入的:createAPIStudentRepository

interface StudentParams {
  query?: string;
  page?: number;
  limit?: number;
}

export const fetchStudents = createAsyncThunk(
  'student/fetch',
  async (
    params: StudentParams,
    { fulfillWithValue, rejectWithValue, extra }
  ) => {
    const { query = '', page = 1, limit = 10 } = params;

   try {
     //TODO: here is the problem, extra() throws an error: "extra" is of type 
     //"unknown"
     const studentRepository = extra();
     const results = await studentRepository.loadAStudents(
       query,
       page,
       limit
     );

     return { results, page, query };
   } catch (error: unknown) {
     console.log(error);
     return rejectWithValue("Error: couldn't fetch Students");
   }
 }
);

问题出在行中。此代码有效,但我收到错误:.TODOTypescript"extra" is of type "unknwon"

关于如何让你知道类型的任何想法?Typescript

参考:

reactjs typescript 依赖注入 redux-thunk

评论


答:

1赞 Drew Reese 11/16/2023 #1

可以显式键入函数。有关详细信息,请参阅与 Typescript 一起使用:createAsyncThunkcreateAsyncThunk

interface StudentParams {
  query?: string;
  page?: number;
  limit?: number;
}

export const fetchStudents = createAsyncThunk<
  // Return type
  { results: Student[], page: number, query: string },
  // Argument
  StudentParams,
  // ThunkApi
  {
    extra: () => StudentRepository
  }
>(
  'student/fetch',
  async (
    params: StudentParams,
    { fulfillWithValue, rejectWithValue, extra }
  ) => {
    const { query = '', page = 1, limit = 10 } = params;

    try {
      const studentRepository = extra();
      const results = await studentRepository.loadAStudents(
        query,
        page,
        limit
      );

      return { results, page, query };
    } catch (error: unknown) {
      console.log(error);
      return rejectWithValue("Error: couldn't fetch Students");
    }
  }
);

或者,您可以强制转换类型。我相信以下方法应该有效。extra

interface StudentParams {
  query?: string;
  page?: number;
  limit?: number;
}

export const fetchStudents = createAsyncThunk(
  'student/fetch',
  async (
    params: StudentParams,
    { fulfillWithValue, rejectWithValue, extra }
  ) => {
    const { query = '', page = 1, limit = 10 } = params;

    try {
      const studentRepository = (extra as () => StudentRepository)();
      const results = await studentRepository.loadAStudents(
        query,
        page,
        limit
      );

      return { results, page, query };
    } catch (error: unknown) {
      console.log(error);
      return rejectWithValue("Error: couldn't fetch Students");
    }
  }
);

评论

0赞 Ale 11/16/2023
感谢您@Drew Reese 的回答。强制转换类型有效。第一个选项会抛出另一个错误,但现在我知道我必须在哪个方向搜索。非常感谢,非常感谢您抽出宝贵时间回答!