键入支持createAsyncthunk生成的动作创建者和参数

发布于 2025-01-22 16:34:50 字数 2114 浏览 1 评论 0 原文

我一直在跟随 redux Essentials bistirals tutorials tutorials 使用 createAsyncthunk 用于生成thunks。在他们的示例像这样的thunk:

export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  async (initialPost) => { // Note: initialPost is an object with 3 props: title, content, user
    const response = await client.post('/fakeApi/posts', initialPost)
    return response.data
  }
)

他们在这样的另一个文件中称其为:

await dispatch(addNewPost({ title, content, user: userId }))

在我的项目中,我已经安装了打字稿和react类型(@type/react )。即使代码是JavaScript,也可以在适当的键入时从VSCODE IDE中获得Intellisense。但是,当我上面做时,我会看到:

​悬停在方法 addNewPost 上,我发现它不需要ARG并返回异步操作。

我如何才能让我的IDE和打字稿键入支持识别所需的正确参数?

我尝试

尝试将一些JSDOC字符串添加到创建 addNewPost 函数之类的功能:

/**
 * addNewPost
 * @returns {(initialPost:{title:string, content:string, user: string}) => void} the returned action create takes an object as arg
 */
export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  async (initialPost) => {
    const response = await client.post('/fakeApi/posts', initialPost)
...

跟随另一个 stack溢出建议< /a>关于如何使用JSDOC描述返回的功能。但这似乎不起作用。

有人有建议吗?

I was following along with the Redux Essentials Tutorials on how to employ createAsyncThunk for generating Thunks. In their example here they create a thunk like so:

export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  async (initialPost) => { // Note: initialPost is an object with 3 props: title, content, user
    const response = await client.post('/fakeApi/posts', initialPost)
    return response.data
  }
)

and they call it in another file like this:

await dispatch(addNewPost({ title, content, user: userId }))

In my project I've installed typescript and react types (@types/react). Even though the code is JavaScript, this gives me intellisense from VSCode IDE on proper typings. However when I do above I see:

typing error about 0 arguments expected

The typings expects 0 arguments but gets one, my object. Hovering over the method addNewPost I see that it takes no args and returns the async action.

0 args for function

How can I have my IDE and typescript typings support recognize the the proper params required?

What I tried

Tried to add some JSDOC string to the created addNewPost function like so:

/**
 * addNewPost
 * @returns {(initialPost:{title:string, content:string, user: string}) => void} the returned action create takes an object as arg
 */
export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  async (initialPost) => {
    const response = await client.post('/fakeApi/posts', initialPost)
...

Following another Stack Overflow suggestion on how to use JSDocs to describe a returned function. but that doesn't seem to work.

Anyone have any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

牛↙奶布丁 2025-01-29 16:34:50

我很幸运地修改JSDOC在 pareloadCreator param createAsyncthunk 函数之类的函数之类的函数:

export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  /**
   * Make POST request to API w. params and create a new record
   * @param {{content: string, title: string, user: string}} initialPost
   * @returns {Promise<{content: string, date: string, id: string, reactions: Object, title: string, user: string}>} returned data
   */
  async (initialPost) => {
    const response = await client.post('/fakeApi/posts', initialPost)
    // The response includes the complete post object, including unique ID
    return response.data
  }
)

因为我更仔细地介绍了 code> createSyncthunk param >作品我意识到为什么这更有意义,因为createSyncthunk本身没有返回这些值,它们是我们传递给它的函数的参数和返回类型。

I had some luck with revising the JSDoc to be specifically above the payloadCreator param inside the createAsyncThunk function like so:

export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  /**
   * Make POST request to API w. params and create a new record
   * @param {{content: string, title: string, user: string}} initialPost
   * @returns {Promise<{content: string, date: string, id: string, reactions: Object, title: string, user: string}>} returned data
   */
  async (initialPost) => {
    const response = await client.post('/fakeApi/posts', initialPost)
    // The response includes the complete post object, including unique ID
    return response.data
  }
)

As I look more closely at how createAsyncThunk works I realize why this makes more sense as createAsyncThunk itself is not returning these values, they are params and return types of the functions we are passing to it.

黯然#的苍凉 2025-01-29 16:34:50

问题是默认 dispatch 从redux类型仅了解 dispatch()函数可以接受普通操作对象。它确实不是知道thunk函数是可以传递的有效的东西。

为了使此代码正确起作用,您需要按照我们的说明进行说明来设置商店并推断基于所有已配置的实际中间件, <代码> <代码>的类型通常包括thunk中间件:

https://redux.js.org/tutorials/typescript-quick-start

然后,使用该 appdispatch 该应用程序,因此当您尝试派遣某些东西时,TS识别出thunks是一件有效的事情。

因此,通常:

// store.ts
const store = configureStore({
  reducer: {
    posts: postsReducer,
    comments: commentsReducer,
    users: usersReducer
  }
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

// hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

// MyComponent.ts
import { useAppDispatch } from '../../app/hooks'

export function MyComponent() {
  const dispatch = useAppDispatch()

  const handleClick = () => {
    // Works now, because TS knows that `dispatch` is `AppDispatch`,
    // and that the type includes thunk handling
    dispatch(someThunk())
  }
}

在特定情况下,您正在使用 createAsyncthunk 。您需要告诉ts ts的参数是什么类型,per https:> https:> https:> https: //redux-toolkit.js.org/usage/usage-with-typescript#createasyncthunk

export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  async (initialPost: InitialPost) => { 
    // The actual `client` in the Essentials tutorial is plain JS
    // But, if we were using Axios, we could do:
    const response = await client.post<ResultPost>('/fakeApi/posts', initialPost)
    // If the `client` was written well, `.data` is of type `ResultPost`
    return response.data
  }
)

The issue is that the default Dispatch type from Redux only understands that the dispatch() function can accept plain action objects. It does not know that a thunk function is a valid thing that can be passed in.

In order to make this code work correctly, you need to follow our instructions for setting up the store and inferring the real type of dispatch based on all the actual middleware that were configured, which would usually include the thunk middleware:

https://redux.js.org/tutorials/typescript-quick-start

Then, use that AppDispatch type elsewhere in the app, so that when you do try to dispatch something TS recognizes that thunks are a valid thing to pass in.

So, typically:

// store.ts
const store = configureStore({
  reducer: {
    posts: postsReducer,
    comments: commentsReducer,
    users: usersReducer
  }
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

// hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

// MyComponent.ts
import { useAppDispatch } from '../../app/hooks'

export function MyComponent() {
  const dispatch = useAppDispatch()

  const handleClick = () => {
    // Works now, because TS knows that `dispatch` is `AppDispatch`,
    // and that the type includes thunk handling
    dispatch(someThunk())
  }
}

Additionally, in your specific case, you're using createAsyncThunk. You need to tell TS what the types are for its arguments, per https://redux-toolkit.js.org/usage/usage-with-typescript#createasyncthunk:

export const addNewPost = createAsyncThunk(
  'posts/addNewPost',
  async (initialPost: InitialPost) => { 
    // The actual `client` in the Essentials tutorial is plain JS
    // But, if we were using Axios, we could do:
    const response = await client.post<ResultPost>('/fakeApi/posts', initialPost)
    // If the `client` was written well, `.data` is of type `ResultPost`
    return response.data
  }
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文