最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Property does not exist on type void - Stack Overflow

programmeradmin4浏览0评论

I am writing a hook to make a post request that returns two properties, sessionId and sessionData. I am using this hook in a ponent. My hook looks like this.

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

And my ponent look like this

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

  return (
    <div />
  )
}

When I try to access data.sessionData on the ponent I get the error that sessionDta does not exist on type void. But If I check the logs on the console I get the same object on the ponent and on the hook. Also If I check on my ponent the typeof data I get an object.

Why I am getting this error?

I am writing a hook to make a post request that returns two properties, sessionId and sessionData. I am using this hook in a ponent. My hook looks like this.

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

And my ponent look like this

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

  return (
    <div />
  )
}

When I try to access data.sessionData on the ponent I get the error that sessionDta does not exist on type void. But If I check the logs on the console I get the same object on the ponent and on the hook. Also If I check on my ponent the typeof data I get an object.

Why I am getting this error?

Share edited Dec 28, 2021 at 13:56 Jared Smith 22.1k5 gold badges49 silver badges94 bronze badges asked Dec 28, 2021 at 12:16 l.legrenl.legren 1611 gold badge4 silver badges16 bronze badges 4
  • 3 You don't return anything from your catch block, so the return type of your function is WhateverTheTypeOfResponseIs | void, depending on which code path happens. Are you using Javascript or Typescript? How/where did you get that error? VSCode intellisense? – Jared Smith Commented Dec 28, 2021 at 12:30
  • 1 Yes, the error es from Intellisense and I am using Typescript. It seems to me that Promise<void> is the default type inferred the Typescript piler. When I try to type the return of the async function I get a "Type WhateverTheTypeOfResponseIs is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-patible constructor value". I am not landing either on the catch block since I get the object on the ponent when I call the hook createOrder from there. Actually if I check the type on my ponent I get also an object – l.legren Commented Dec 28, 2021 at 13:02
  • 3 I would suggest to move your error handling logic inside the useEffect hook when you call via .catch, e.g. createOrder().then(...).catch(...). Then simplify your createOrder function to just simply return postWithToken(...). Also, createOrder is not a hook - it's just a simple function. – goto Commented Dec 28, 2021 at 14:00
  • 3 Also, looks like you're using TypeScript and not providing the return type of createOrder, e.g. createOrder = async (): Promise<SomeType>, which is why it's plaining. – goto Commented Dec 28, 2021 at 14:04
Add a ment  | 

3 Answers 3

Reset to default 3

You don't return anything from your catch block, so the return type of your function is Promise<WhateverTheTypeOfResponseIs | void> (N.B. async functions implicitly return a Promise, and if your postWithToken function doesn't return anything then it's just Promise<void>), depending on which code path happens.

In the future you can avoid unpleasant and slightly problematic to debug issues like this by giving your functions an explicit return type and in this case the piler will let you know that your expectation was violated:

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

The types in the example I created may be different (you'll need to sub with the actual types from your code) but you should get the idea. You can fix this by any of the following:

  1. Explicitly return something of the correct type from the catch block.
  2. Change your return type to Promise<CorrectType | undefined>.
  3. Move the error handling to the caller as suggested by goto1 in the ments.

Also note that as goto1 points out in the ments on the question, your hook isn't actually a hook (which is fine, but be careful of terminology).

This sounds like a TypeScript issue, so I suggest to provide the proper return type for your createOrder function.

// 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 ponent
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 */)
  }, [])
}

open tsconfig.json file and change

"strict": true,

into

"strict": false,

this usually works for me

check out https://v2.vuejs/v2/guide/typescript.html for more information

发布评论

评论列表(0)

  1. 暂无评论