Is it possible for me to create a union type that connects parameters and responses in a cohesive manner

I'm interested in creating a custom type that functions can use to indicate to callers that an input parameter of a specific type corresponds to a certain output type.

For instance, consider the following scenario:

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();
}

// This currently throws an error because `PostData` cannot be
// assigned to `UserData | undefined`
const response: UserData | undefined = await getRequest("/user/");

Playground link.

While I understand that function overloads could achieve something similar, I'm seeking a way to reuse ResponseMap in other functions. Is this achievable in TypeScript?

Answer №1

Sure thing, all you have to do is obtain and extract the correct 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 URLs like /user/123 will be supported!

Interactive Playground

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Framer Motion's AnimatePresence feature fails to trigger animations when switching between pages

I'm running into issues with the Framer Motion library, specifically with the AnimatePresence transition. I've managed to make it work in normal situations, but when I encapsulate my Routes within a custom implementation, the exit animation fails ...

Enhancing Angular2 Routing with Angular4 UrlSerializer for Seamless HATEOAS Link Integration

As a newcomer to Angular4, I am currently exploring how to consume a HATEOAS API. My goal is to either pass an object that contains the self reference or the self reference link itself through the routing mechanism (for example, by clicking on an edit link ...

Events bound to JSX elements created in an array map are not being triggered by React

My current task involves working on a compact react + typescript (1.6) application designed for editing slideshows. The functionality of the app is straightforward. A sidebar on the left displays all existing slides, and upon clicking, a canvas appears on ...

Encountering the ExpressionChangedAfterItHasBeenCheckedError error during Karma testing

Testing out some functionality in one of my components has led me to face an issue. I have set up an observable that is connected to the paramMap of the ActivatedRoute to retrieve a guid from the URL. This data is then processed using switchMap and assigne ...

What is the best way to selectively pass certain values to the args object?

Is there a way in TypeScript to pass only one argument into args and have other values be default without using "args = {}" or declaring defaults within the function to avoid issues with intellisense? function generateBrickPattern ( wallWidth: number, ...

Dynamic Angular component loading with lazy loading

In my Angular 4.1.3 project, I am currently developing a mapping application that incorporates lazy-loading for various tool modules. At present, the tools are loaded within the map using a router-outlet. However, I now need to expand this functionality to ...

Exploring the possibilities of Ionic 2 with Web Audio API

I am encountering issues while using the Web Audio API with Ionic 2. Despite my efforts, I keep running into errors. It seems that the problem lies within the TypeScript compiler. I attempted to resolve it by adding "es2015.promise", but to no avail. The e ...

Retrieve type definitions for function parameters from an immutable array containing multiple arrays

My current challenge involves implementing a function similar to Jest's test.each iterator: // with "as const" forEach([ [ 1, 2, 3 ], [ "a", "b", "c" ], ] as const, (first, second, third) => { // ...

TS2345: Cannot assign type '(item: cType) => cType' to type '(value: Object, index: number, array: Object[]) => cType' within the parameter

I am currently working on a project using Angular 13 and Typescript 4.5.2. In addition, I am incorporating the Syncfusion library in my development process, specifically utilizing the datagrid component for managing table data. For reference, you can che ...

Switch from Gulp-TSLint to Gulp-ESLint for enhanced code analysis!

I am currently in the process of updating a Gulp task that uses gulp-tslint to now use gulp-eslint. The code snippet below outlines the changes I need to make: const { src } = require('gulp'); const config = require('./config'); const ...

How can I ensure that PrimeNG is functioning properly?

I'm encountering some difficulties setting up PrimeNG correctly to utilize its rich text editor. Despite installing all the necessary components, it's still not functioning as expected. https://i.stack.imgur.com/4kdGf.png This is my package.jso ...

Bring in all subdirectories dynamically and export them

Here is what I currently have: -main.js -routeDir -subfolder1 -index.js -subfolder2 -index.js ... -subfolderN -index.js Depending on a certain condition, the number of subfolders can vary. Is there a way to dynam ...

The Angular template is throwing an error stating that c_r1.getCatType is not a valid function

Within my Angular project (version 9.1.0), I have a class structured like this: export class Contract { contractName: string; limit: number; public getCatType(): string{ if(this.limit > 0) return 'p'; return &ap ...

Converting a specific string format to a Date object in TypeScript

I am in need of a solution to convert strings with the given format into Date objects using TypeScript: var dateTimeString:string = "20231002-123343" I have created my own method as shown below: var dateTime:string[] = dateTimeString.split(" ...

Setting a default value for a select-option in Angular can be done by initializing the

How can I set a default value of 'John' for a select option in the ngOnInit function when the page loads? I'm not entirely sure if I'm using the select option correctly. Please let me know if there's an error in my approach. I att ...

Typescript objects may contain keys that are dependent on certain parameters

I have a challenge with constructing an object that requires querying multiple database tables, resulting in a time-consuming process. To address this issue, clients of the object need to specify which specific parts they require. For example, let's c ...

How to open a print preview in a new tab using Angular 4

Currently, I am attempting to implement print functionality in Angular 4. My goal is to have the print preview automatically open in a new tab along with the print popup window. I'm struggling to find a way to pass data from the parent window to the c ...

Leverage the compiler API to perform type inference

Exploring TypeScript's compiler API for basic type inference has proven to be a challenge with limited helpful information found in documentation or online searches. My goal is to create a function inferType that can determine and return the inferred ...

Diverse Range of Exports Available in React Component Library

I have been working on developing a component library consisting of multiple independent components. My objective is to enable users to easily import and use these components in their projects, similar to the following: import One from 'component-lib ...

What is the best way to insert information into my SQLite database?

Hey there! I'm new to programming and recently started working on an IONIC App. However, I've hit a roadblock. My goal is to create a phone book feature where users can get random JSON contacts and save them to their sqlite database. Here's ...