我正在try 定制Redux工具包附带的中间件,以增加额外的参数. 这个额外的参数是存储库的实现.

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

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中,我想使用我在配置store 时注入的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");
   }
 }
);

这个问题在TODO%的范围内.此代码可以工作,但我得到一个Typescript错误:"extra" is of type "unknwon".

你知道怎么才能让Typescript知道是哪种类型吗?

参考:

推荐答案

您可以显式键入createAsyncThunk函数.有关详细信息,请参阅Usage with Typescript: createAsyncThunk.

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");
    }
  }
);

或者你也可以 Select 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");
    }
  }
);

Typescript相关问答推荐

Typescript如何从字符串中提取多个文本

如何根据数据类型动态注入组件?

键集分页顺序/时间戳上的筛选器,精度不相同

具有动态键的泛型类型

部分类型化非 struct 化对象参数

声明文件中的类型继承

@TANSTACK/REACT-QUERY中发生Mutations 后的数据刷新问题

如何在使用条件类型时使用void

如何在脚本中输入具有不同数量的泛型类型变量的函数?

避免混淆两种不同的ID类型

类型推断对React.ForwardRef()的引用参数无效

在Cypress中,您能找到表格中具有特定文本的第一行吗?

使用Type脚本更新对象属性

如何从接口中省略接口

使用&reaction测试库&如何使用提供程序包装我的所有测试组件

TypeScript:如何使用泛型和子类型创建泛型默认函数?

是否使用类型将方法动态添加到类?

为什么类方法参数可以比接口参数窄

我应该使用服务方法(依赖于可观察的)在组件中进行计算吗?

如何强制对象数组中的对象属性具有非空字符串值?