如何正确使用带有 typescript 的 createAsyncThunk 函数?
Posted
技术标签:
【中文标题】如何正确使用带有 typescript 的 createAsyncThunk 函数?【英文标题】:How do I properly use createAsyncThunk function with typescript? 【发布时间】:2021-12-24 09:07:10 【问题描述】:你可以找到完整的项目here。
我有以下代码:
extraReducers: (builder) =>
builder
.addCase(getTodosAsync.fulfilled, (state, action:any) =>
return action.payload.todos
)
.addCase(addTodoAsync.fulfilled, (state, action:any) =>
state.push(action.payload.todo)
)
.addCase(toggleCompleteAsync.fulfilled, (state, action:any) =>
const index = state.findIndex(
(todo) => todo.id === action.payload.todo.id
)
state[index].completed = action.payload.todo.completed
)
.addCase(deleteTodoAsync.fulfilled, (state, action:any) =>
return state.filter((todo) => todo.id !== action.payload.id)
)
但我想正确键入回调的动作参数,换句话说,摆脱“任何”类型。我已经发现正确的方法是键入 createAsyncThunk,但是直到现在我都不知道该怎么做。
文件的其余代码如下:
import
createAsyncThunk,
createSlice,
PayloadAction
from '@reduxjs/toolkit';
// import AsyncThunkFulfilledActionCreator from '../../node_modules/@reduxjs/toolkit/src/createAsyncThunk'
import nanoid from 'nanoid';
interface propsPayload
title?: string,
id?: string,
completed?: boolean
const initialState = [
] as Array<propsPayload>
export const getTodosAsync = createAsyncThunk(
'todos/getTodosAsync',
async () =>
const resp = await fetch('http://localhost:7000/todos');
if (resp.ok)
const todos = (await resp.json()) ;
return todos ;
);
export const addTodoAsync = createAsyncThunk(
'todos/addTodoAsync',
async (payload: propsPayload) =>
const resp = await fetch('http://localhost:7000/todos',
method: 'POST',
headers:
'Content-Type': 'application/json',
,
body: JSON.stringify( title: payload.title ),
);
if (resp.ok)
const todo = await resp.json();
return todo ;
);
export const toggleCompleteAsync = createAsyncThunk(
'todos/completeTodoAsync',
async (payload: propsPayload) =>
const resp = await fetch(`http://localhost:7000/todos/$payload.id`,
method: 'PATCH',
headers:
'Content-Type': 'application/json',
,
body: JSON.stringify( completed: payload.completed ),
);
if (resp.ok)
const todo = await resp.json();
return todo ;
);
export const deleteTodoAsync = createAsyncThunk(
'todos/deleteTodoAsync',
async (payload: propsPayload) =>
const resp = await fetch(`http://localhost:7000/todos/$payload.id`,
method: 'DELETE',
);
if (resp.ok)
return id: payload.id ;
);
export const todoSlice = createSlice(
name: 'todos',
initialState: initialState,
reducers:
addTodo: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) =>
const todo =
id: nanoid(),
title: action.payload.title,
completed: false,
;
state.push(todo);
,
toggleComplete: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) =>
const index = state.findIndex((todo) => todo.id === action.payload.id);
state[index].completed = action.payload.completed;
,
deleteTodo: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) =>
return state.filter((todo) => todo.id !== action.payload.id);
,
,
extraReducers: (builder) =>
builder
.addCase(getTodosAsync.fulfilled, (state, action:any) =>
return action.payload.todos
)
.addCase(addTodoAsync.fulfilled, (state, action:any) =>
state.push(action.payload.todo)
)
.addCase(toggleCompleteAsync.fulfilled, (state, action:any) =>
const index = state.findIndex(
(todo) => todo.id === action.payload.todo.id
)
state[index].completed = action.payload.todo.completed
)
.addCase(deleteTodoAsync.fulfilled, (state, action:any) =>
return state.filter((todo) => todo.id !== action.payload.id)
)
);
export const addTodo, toggleComplete, deleteTodo = todoSlice.actions;
export default todoSlice.reducer;
但如果我从操作中删除“任何”,就会发生这种情况:
Object is possibly 'undefined'.ts(2532)
(parameter) action: PayloadAction<
todos: any;
| undefined, string,
arg: void;
requestId: string;
requestStatus: "fulfilled";
, never>
Object is possibly 'undefined'.ts(2532)
(property) payload:
todos: any;
| undefined
【问题讨论】:
您是否在redux-toolkit.js.org/usage/… 阅读了有关如何将其与打字稿一起使用的文档? 【参考方案1】:根本不要输入动作类型。如果您什么都不做,则可以从您的 asyncThunk 类型正确推断。
.addCase(addTodoAsync.fulfilled, (state, action) =>
就像state
自动是正确的类型一样,action
也是 - 由addTodoAsync
调度的已完成操作的类型。
【讨论】:
但是如果我删除第一个函数的'any',例如,会发生以下错误: Object is possible 'undefined'.ts(2532) (property) payload: todos: any; | undefined 没有可用的快速修复方法 因为这是正确的。由于if
语句,您的代码并不总是return
。如果一个函数没有return
,它会返回undefined
。
非常感谢!如果条件不成功,我编辑了代码以返回初始状态,并且它起作用了。以上是关于如何正确使用带有 typescript 的 createAsyncThunk 函数?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Typescript 中正确使用 React.lazy() 来导入带有泛型类型参数的反应组件?
带有 Typescript 和 ThemeProvider 的样式化组件。啥是正确的类型?
如何在带有 TypeScript 的 React-Native 中使用 styled-component 键入无状态功能组件?