Home > Software engineering >  Property 'Error' does not exist on type 'MovieData | ResponseError'. Property &#
Property 'Error' does not exist on type 'MovieData | ResponseError'. Property &#

Time:08-02

Answered

So I have following interfaces: MovieData

export interface MovieData {
  Poster: string;
  Title: string;
  Plot: string;
  imdbID: string;
}

and interface ResponseError

export interface ResponseError {
  Response: 'False',
  Error: string,
}

I also have function getMovie() thet returns Promise, resolve type is MovieData , and reject type is ResponseError

import { MovieData } from './types/MovieData';
import { ResponseError } from './types/ReponseError';

const API_URL = 'https://www.omdbapi.com/?apikey=**********';

export function getMovie(query: string): Promise<MovieData | ResponseError> {
  return fetch(`${API_URL}&t=${query}`)
    .then(res => res.json())
    .catch(() => ({
      Response: 'False',
      Error: 'unexpected error',
    }));
}

In FindMovie function component I invoke handleSubmit function, and pass search string inside getMovie function. In then() method of promise I want to check either promise was rejected , or fullfiled. In case rejected - I check if res object has property Error. type of res - if you hover mouse over res property in then() - res: MovieData | ResponseError

import { useState } from 'react';
import { getMovie } from '../../api';

export const FindMovie: React.FC = () => {
  const [search, setSearch] = useState<string>('');
  const [error, setError] = useState<boolean>(false);

  const handleSubmit = () => {
    if (search === '') {
      return;
    }

    getMovie(search)
      .then(res => {
        if (res?.Error) {
          console.log(res?.Error)
        }
      });

    setError(false);
  };

QUESTION!!!!!!!!

in terminal I recieve error: Property 'Error' does not exist on type 'MovieData | ResponseError'. Property 'Error' does not exist on type 'MovieData'.

I tried to use import separetly interface ResponseError to file with findMovie function component

import { ResponseError } from '../../types/ReponseError';

and to perform next check

.then(res => {
   if (res instanceof ResponseError) {
       console.log(res?.Error)
   }
});

But I recieve even wierder error message: Attempted import error: 'ResponseError' is not exported from '../../types/ReponseError'.

Will be glad for every advise.

CodePudding user response:

You need a type guard here to check if your object is of type ResponseError.

You cannot use instanceof here, since that is used to check if an object belongs to a certain class.

Whereas in your case, you are using interface and type.

Defining a type guard like:

function isResponseError(obj: any): obj is ResponseError {
    return obj.Error !== undefined;
}

and then doing:

.then(res => {
   if (isResponseError(res)) {
       console.log(res.Error)
   }
});

should solve your problem.

You can check out this stackoverflow answer for more info on type guards vs instanceof: How to check the object type on runtime in TypeScript?

CodePudding user response:

So, thats how I implemented type guard

if (res?.Title === undefined) {
  setError(true);
}

But I also completly rewrote fetch request. Honestly , now its wierd , result variable will be of Type MovieData errelevent of object content. But it Just Works.

In the question problem was: I was checking for property of Moviedata type object - typescript said that ResponseError interface doesn't have that property - because promise returned object of either MovieData or ResponseError;

export async function getMovie(query: string): Promise<MovieData > {
  const res = await fetch(`${API_URL}&t=${query}`);
  const result = await res.json();

  if (result.response === 'False') {
    throw new Error(`${result.statusText}`);
  }

  return result;
}
  • Related