Home > Software design >  Can I define a union type linking parameters and responses together?
Can I define a union type linking parameters and responses together?

Time:09-23

I'd like to define a type that can be used by functions to inform callers that an input parameter of a given type leads to its corresponding output type.

So for example, something like this:

type ResponseMap =
  { requestPath: "/user/", response: UserData } |
  { requestPath: "/posts/", response: PostData };

async function getRequest<Value extends ResponseMap>(
  path: Value["requestPath"]
): Promise<Value["response"] | undefined> {
  const response = await fetch(path);
  return response.json();
}

// Currently errors because `PostData` can't be
// assigned to `UserData | undefined`
const response: UserData | undefined = await getRequest("/user/");

Playground link.

Now, I know I can achieve something like this with function overloads, but I want to reuse ResponseMap in other functions as well. Is that possible in TypeScript?

CodePudding user response:

Yep, just need to get and extract the right type:

type ResponseMap =
  { requestPath: "user", response: UserData } |
  { requestPath: "posts", response: PostData };

type GetResponseType<Path> = Path extends `/${infer Type}/${string}` ? Extract<ResponseMap, { requestPath: Type }>["response"] : never;

Now even paths like /user/123 will also work!

Playground

  • Related