How to cast return type of function based on argument type?

Viewed 347

How can I cast response.body to the type of options.responseType argument? TypeScript playground

The code block bellow is a simplified version of my code... many more options exist.

import got from "got"

interface Options {
  responseType?: "buffer" | "json"
}

const get = async (url: string, options?: Options) => {
  let response = await got.get(url, {
    responseType: options?.responseType ?? "json"
  })
  return response.body
}
2 Answers

The simplest solution would be to use overloads:

import got from "got"

interface Options {
  responseType?: "buffer" | "json"
}


async function get (url: string, options: Options & { responseType: "buffer" }) : Promise<Buffer>
async function get(url: string, options: Options & { responseType: "json" }): Promise<object>
async function get(url: string, options?: Options): Promise<unknown>
async function get (url: string, options?: Options) {
  let response = await got.get(url, {
    responseType: options?.responseType
  })
  return response.body
}

let buffer = get("", { responseType: "buffer"})
let object = get("", { responseType: "json" })
let unknown = get("")

Playground Link

Use generics T

import got from "got";

type ResponseType = "buffer" | "json";

const get = async <T>(url: string, responseType: ResponseType): Promise<T> => {
  let response = await got.get(url, {
    responseType: responseType
  });
  return response.body;
};

get<string>("url", "json");
Related