1

I'm fighting with property success which is definited in API (recaptcha).

/**
   * The structure of response from the veirfy API is
   * {
   *  "success": true|false,
   *  "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
   *  "hostname": string,         // the hostname of the site where the reCAPTCHA was solved
   *  "error-codes": [...]        // optional
    }
   */

Below I tried use optional chaining to fix that problem, but it does not work. I have tried use interface on different sides, but I can't fix that again with it.

Below code:

import fetch from "node-fetch"
//...
try {
const response = await fetch(
  `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.GOOGLE_RECAPTCHA_SECRETKEY}&response=${captcha}`,
  {
    headers: {
      "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
    },
    method: "POST",
  }
);

const captchaValidation = await response.json();
if(captchaValidation?.success) // error: Property 'success' does not exist on type '{}'

} catch (error) {}

How can I get access to that property?

DonEmil
  • 37
  • 3
  • That's a typescript error. You have to tell TypeScript what "type" `captchaValidation` has, and therefor what properties are available. – Andreas Oct 06 '22 at 08:32
  • I know that, but I have not idea how to implement that "type" to `captchaValidation` :/ Need help – DonEmil Oct 06 '22 at 08:42

2 Answers2

1

It seem shat .json is not type aware and it returns Promis<never< - .json method

I can propose a solution you need to delcare the Captcha types and tell typescript believe me it is this type

export interface CaptchaResponse {
  success: boolean;
  challenge_ts: string;
  hostname: string;     
  error-codes?: any[];
}


....
const rawResponse = await response.json();
// next line is nothing more just saying - believe me it is this type. It will not do type checking
const typedRespone = rawResponse as CaptchaResponse;
if(typedRespone.success)

....
Svetoslav Petkov
  • 1,117
  • 5
  • 13
0

You can create an interface and declare that the response is that interface. Then TypeScript is told that a success property should exist.

export interface ApiResponse {
  success: boolean;
  challenge_ts: string;
  hostname: string;     
  error-codes?: any[];
}

Then declare it as that type:

const captchaValidation: ApiResponse = await response.json();
CoderApprentice
  • 425
  • 1
  • 6
  • 21
  • According to your second option I have got an error: `Type 'unknown' is not assignable to type 'ApiResponse'.` The first option also throw an error: `Type 'Response' is missing the following properties from type 'ApiResponse': success, challenge_ts, hostname` – DonEmil Oct 06 '22 at 08:55
  • 1
    Yeah wasn't sure which one should return your desired object, never mind the first line then. Seems TypeScript already knows your `await response.json()` returns `unknown` so then you could do type-casting like the other answer suggests. – CoderApprentice Oct 06 '22 at 09:05