tnkh
tnkh

Reputation: 1839

Typescript requires different return type depending on scenario

Hi I am new to typescript and need some understanding on this particular stuff.

I am returning an axios api response with the following format:

async function callApi(value:string):Promise<string>{
  return await axios.post('/api/something', { key: value})
}

This works. But if I want to refactor it to become

async function callApi(value:string):Promise<string>{
  const result = await axios.post('/api/something', { key: value})
  console.log(result)
  return result
}

It will throw TS lint error saying Type 'AxiosResponse' is missing the following properties from Type 'AxiosResponse<any>' is not assignable to type 'string'

And I tried

async function callApi(value:string):Promise<AxiosResponse<string>>{
  const result = await axios.post('/api/something', { key: value})
  console.log(result)
  return result
}

but it didnt work. Any idea why the same return result requires different typings? How should I make it work?

Upvotes: 1

Views: 2389

Answers (1)

boop_the_snoot
boop_the_snoot

Reputation: 3247

Bissecting your example here:

// Function is ALWAYS expected to return Promise<string>
async function callApi(value:string): Promise<string> {   
  const result = await axios.post('/api/something', { key: value} )
  // Because you have awaited here ^^^, its converted to `AxiosResponse<string>` instead of `Promise<string>`
  return result 
  // Thus, ^^^ `result` is of type 'AxiosResponse<string>', which contradicts function's expected return type, ie Promise<string>
}

Your requirement can be written in multiple ways, like so:

Example 1:

function callApi(value:string): Promise<AxiosResponse<string>> {
  return axios.post('/api/something', { key: value});
}

Example 2:

async function callApi(value:string): AxiosResponse<string> {  
  return await axios.post('/api/something', { key: value} );
}

Example 3:

async function callApi(value:string): AxiosResponse<string> {  
  const result = await axios.post('/api/something', { key: value} );
  return result;
}

Example 4:

async function callApi(value:string): string {  
  const result = await axios
                       .post('/api/something', { key: value} )
                       .then(r => r.json()); // This will auto-convert to expected return type
  return result; // its type is `string`, instead of `AxiosResponse<string>`
}

Usage of all the examples given above:

callApi('test').then(...);
// OR
const resp = await callApi('test'); // to use like this, calling function should also be marked `async`

Upvotes: 1

Related Questions