Typescript : Adding types to a function that takes in a string and returns a different promise based on the string
The problem here is that the interface IAnimal is not what those apis return. You want to return that interface from your function, but those APIs should have their own interface representing the response data.
interface DogApiResponse {
  message: string
  status: string
}

interface FoxApiResponse {
  image: string
}

interface Animal {
  status: string
  image: string | null
}

To generalize the set of available animal types I propose to also add interface for the fetching part of individual APIs.
declare type RandomAnimalFactory = () =&gt; Promise&lt;Animal&gt;

Now we declare two factories - for dogs and foxes
const dogFactory: RandomAnimalFactory = async () =&gt; {
  const result: DogApiResponse = await fetch(dogApiUrl).then(data =&gt; data.json())
  if (result.status !== 'success') {
    throw new Error('Dog API railure')
  }
  return {image: result.message, status: 'success'}
}

const foxFactory: RandomAnimalFactory = async () =&gt; {
  const result: FoxApiResponse = await fetch(foxApiUrl).then(data =&gt; data.json())
  return {image: result.image, status: 'success'}
}

The we can have the named animal factory work like this
declare type NamedAnimalFactory = (name: string) =&gt; Promise&lt;Animal&gt;


const createRandomNamedAnimalFactory = (randomFactories: {[key: string]: RandomAnimalFactory}): NamedAnimalFactory =&gt; {
  return async (name) =&gt; {
    const factory = randomFactories[name.trim().toLowerCase()]
    if (!factory) {
      return {image: null, status: 'failure'}
    }

    try {
      return await factory()
    } catch {
      return {image: null, status: 'failure'}
    }
  }
}

const getAnimal: NamedAnimalFactory = createRandomNamedAnimalFactory({
  dog: dogFactory,
  fox: foxFactory,
})
```