#Property 'access_token' does not exist on type 'string | getAccessTokenResponse'.

1 messages · Page 1 of 1 (latest)

spiral marten
#
type getAccessTokenResponse = {
  access_token: string;
  token_type: string;
  expires_in: number;
  scope: string;
};

type getTopTracksResponse = {
  tracks: Track[];
};

type Track = {
  artist: string;
  title: string;
};


const getTopTracks = async () => {
const { access_token } = await getAccessToken(); //Property 'access_token' does not exist on type 'string | getAccessTokenResponse'.
    try {
      const { data, status } = await axios.get<getTopTracksResponse>(
        TOP_TRACKS_ENDPOINT,
        {
          headers: {
            Authorization: `Bearer ${access_token as string}`,
          },
        }
      );
      console.log(data);
      return data;
    } catch (error) {
      if (axios.isAxiosError(error)) {
        console.log("error message: ", error.message);
        return error.message;
      } else {
        console.log("unexpected error: ", error);
        return "An unexpected error occurred";
      }
    }
};

I'm new to typescript. using access_token: any worked in dev but I don't want to use that in production for obvious reasons. Any knows how to solve this?

kind marten
#

have you tried reading the error message? @spiral marten

kind marten
spiral marten
kind marten
#

not really

#

your getAccessToken function returns a union

#

2 possible types

#

either a string

#

or an object

#

you are trying to access a property that only exists on the object
but what would happen if it's a string you get?

spiral marten
#

but didnt i define getAccessTokenResponse to return access_token as string strictly

kind marten
#

based on your other function (getTopTracks ) I can emmediately see something that is not ideal

kind marten
#

if getTopTracks succeeds, you return the data
but if it fails, you return a string that is the error message

spiral marten
kind marten
#

try only returning 1 type of data

#

if the function throws an error, you can always handle the error later/elsewhere in the code

#

why should the getTopTracks function handle the error?

#

it shouldn't, there is no benefit catching the error at that level in the code

#

just return the data if you have some, or let the function throw if there is an error

spiral marten
#

so what i understand is

#

there is no point of getTopTracks handling the error

kind marten
#

right

#

it's only a function to retrive some data

#

it should not display errors

#

that should be a different part of the code

spiral marten
#

okay

kind marten
#
import axios from "axios";

interface AccessToken {
    access_token: string;
    token_type: string;
    expires_in: number;
    scope: string;
}
declare function getAccessToken(): Promise<AccessToken>;


interface TopTracks {
    tracks: Track[];
}
interface Track {
    artist: string;
    title: string;
}
declare const TOP_TRACKS_ENDPOINT: string;
const getTopTracks = () => getAccessToken()
    .then(({ access_token }) => axios
        .get<TopTracks>(TOP_TRACKS_ENDPOINT, { headers: { Authorization: `Bearer ${access_token}` } }));

#

that's what the code looks like without all that error handing
much lighter

spiral marten
kind marten
#

yes, because you are not returning a string anymore

#

only the AccessToken object

#

also, a few things, try using PascalCase for the names of your types, and camelCase for your variables/function

spiral marten
#

thanks for the help man i really appreciate it 😄

spiral marten
kind marten
#

you should handle the error at a higher level in the code, were you are trying to get the top tracks for example

spiral marten
#

i get it now

#

noob question but why are you using declare

kind marten
#

thedeclare keyword is useful to tell the TypeScript compiler some variable/function exists

#

but without the need to provide a value or an implementation

#

it just tell TS a function named X with parameters of type P and ofreturn type R exsists, but we don't care about the code

#

if you compile code using the declare keyword, you'll see it doesn't emit the variable or function

#

notice how getAccessToken is missing on the right side of the screen (JS code)

#

it's mainly useful when writing type declaration files (.d.ts files), to add types to existing JS code

#

or when debugging some code in the TS playground, where we don't run the code, we only want the types to be checked

spiral marten
#

Oh so its like a placeholder