属性 在类型 void 上不存在

Property does not exist on type void

我正在编写一个钩子来制作一个 post 请求 returns 两个属性,sessionIdsessionData.我在一个组件中使用这个钩子。我的钩子是这样的。

export const createOrder = async () => {
  try {
    const response = await postWithToken(API_ROUTES.PAYMENT_SESSION, token || '', 
    testObject)
    console.log("FROM HOOK", response)
    return response
    } catch (err: any) {
      console.log(err)
    }
  }

我的组件看起来像这样

const myComponent = () => {
  useEffect(() => {
    createOrder().then(data => {
      console.log("Session Data",data.sessionData)
      console.log("FROM PAGE", data)
    })
  }, [])

  return (
    <div />
  )
}

当我尝试访问组件上的 data.sessionData 时,我收到错误消息,指出 sessionDta 在 void 类型上不存在。但是如果我检查控制台上的日志,我会在组件和挂钩上得到相同的对象。另外,如果我检查我的组件的数据类型,我会得到一个对象。

为什么会出现此错误?

你没有从你的 catch 块中 return 任何东西,所以你的函数的 return 类型是 Promise<WhateverTheTypeOfResponseIs | void> (N.B。async 函数隐式 return 一个 Promise,如果你的 postWithToken 函数没有 return 任何东西,那么它只是 Promise<void>),这取决于发生的代码路径。

将来你可以通过给你的函数一个明确的 return 类型来避免令人不快和稍微麻烦的调试问题,在这种情况下,编译器会让你知道你的期望被违反了:

const postWithToken = async (route: string, token: string, obj: any): Promise<boolean> => {
  try {
    const resp = await fetch(
      route,
      { 
        method: 'POST',
        body: JSON.stringify(Object.assign(obj, { token }))
      },
    )
    return Boolean(resp.status < 400 && resp.status >= 200)
  } catch (err) {
    console.error(err)
    return false
  }
}

const API_ROUTES = {
    PAYMENT_SESSION: 'whatever'
}

const testObject = {
  token: ''
}

const token = ''

const createOrder = async (): Promise<boolean> => { // <-- squiggles
  try {
    const response = await postWithToken(API_ROUTES.PAYMENT_SESSION, token || '', 
    testObject)
    console.log("FROM HOOK", response)
    return response
  } catch (err: any) {
    console.log(err)
  }
}

Playground

我创建的示例中的类型可能不同(您需要使用代码中的实际类型),但您应该明白了。您可以通过以下任一方法解决此问题:

  1. 明确地 return 来自 catch 块的正确类型。
  2. 将您的 return 类型更改为 Promise<CorrectType | undefined>
  3. 按照评论中 goto1 的建议将错误处理移至调用方。

另请注意,正如 goto1 在对该问题的评论中指出的那样,您的钩子实际上并不是一个钩子(这很好,但要注意术语)。

这听起来像是一个 TypeScript 问题,因此我建议为您的 createOrder 函数提供正确的 return 类型。

// Use the official type for SessionData, if you have it available,
// otherwise create a new type that properly matches its shape
type CreateOrderResult = {
  sessionData: SessionData;
}

// No need for `async/await` here, just return the `postWithToken`
// and handle errors inside your component
export const createOrder = (): Promise<CreateOrderResult> => {
  // ...
  return postWithToken(
    API_ROUTES.PAYMENT_SESSION, 
    token || '',
    testObject
  )
}

// MyComponent.tsx
const MyComponent = () => {
  useEffect(() => {
    createOrder()
      .then(data => console.log(data.sessionData))
      .catch(error => /* handle errors appropriately */)
  }, [])
}

打开 tsconfig.json 文件并 变化

“严格”:正确,

进入

“严格”:错误,

这通常适合我

查看https://v2.vuejs.org/v2/guide/typescript.html了解更多信息