What is the best way to sort a union based on the existence or non-existence of a specific

My API response comes in the form of a IResponse, which can have different variations based on a URL search parameter.

Here is how I plan to utilize it:

const data1 = await request<E<"aaa">>('/api/data/1?type=aaa');
const data2 = await request<E<"bbb">>('/api/data/1?type=bbb');

function request<T>(
  url: string
): Promise<T> {
  return fetch(url, config)
    .then((response) => response.json())
    .then((data) => data as T);
}

//index.ts

import {
  paths,
} from "./autoGeneratedTypes";

type IResponse =
  paths["/api/data/{id}"]["get"]["responses"]["200"]["content"]["application/json"];

export type E<T extends "aaa" | "bbb"> = T extends "aaa"
  ? Omit<IResponse, "ca">
  : Pick<IResponse, "ca">;

export type F = E<"aaa">["bb"];

Encountering an error at

Pick<IResponse, "ca">
stating
Type 'string' does not satisfy the constraint 'never'

To avoid directly referencing schemas C or B due to possible schema name changes, I require a type that will correctly extract the API response type from IResponse.

//autoGeneratedTypes.ts
/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */

export interface paths {
  "/api/data/{id}": {
    /** @description get the data */
    get: {
      responses: {
        /** @description Retrieved the data successfully */
        200: {
          content: {
            "application/json": components["schemas"]["D"];
          };
        };
      };
    };
  };
}

export interface components {
  schemas: {
    D: components["schemas"]["C"] | components["schemas"]["B"];
    C: {
      ca: components["schemas"]["B"][];
    };
    B: {
      ba: string;
      bb: components["schemas"]["A"][];
    };
    A: {
      aa: string;
      ab: string | null;
    };
  };
}

Link to Typescript Playground

Answer №1

If you are dealing with union types in TypeScript, the Extract<T, U> and Exclude<T, U> utility types can be very helpful. These types allow you to filter out members of a union type based on certain criteria.

To achieve this, you can use something like:

type E<T extends "aaa" | "bbb"> =
  T extends "aaa" ? Exclude<IResponse, { ca: any }> : Extract<IResponse, { ca: any }>

which will give you the desired result.

It's worth noting that using Pick<T, K> and Omit<T, K> might not work well when dealing with union types, as they do not distribute over unions in TypeScript.

For a more interactive example, check out this Playground link.

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

Looking to determine if two elements exist within an array? Seeking a boolean result based on their presence

Consider the following array of objects: quesListArray = [ { QuestionTypeID : 1, QuestionTypeName : 'Rating' }, { QuestionTypeID : ...

RxJs: Generating an observable based on changes in a field's value

Is there a way to generate an Observable using the variable this.pending as its source? I'm looking to create an Observable that will produce a new feed each time the value of this.pending changes. For example, if I update this.pending to be false i ...

Encountering a TypeScript error while calling a Vue lifecycle hook method

Struggling to call a method in a Vue root component from a lifecycle method in typescript? See below for a simple example that showcases this issue: import Vue from "vue"; class Game { a: number; b: number; constructor() { this.a = 3; ...

Firestore - Insert new entries into an array in an existing document using Typescript

After retrieving data from Firestore using Firebase and implementing pagination function, I encounter an issue when attempting to add the new values to an array. Specifically, TypeScript raises an error message when I try to invoke the setState hook. int ...

What are the steps to effectively implement the useEffect hook in React?

I'm facing an issue where I am trying to return a function that utilizes useEffect from a custom usehook, but I keep getting the error "useEffect is called in a function which is neither a react function component nor a custom hook." Here's what ...

Issue reported: "Usage of variable 'someVar' before assignment" ; however, it is being properly assigned before usage

This piece of code showcases the issue: let someVar: number; const someFunc = async () => { someVar = 1; } await someFunc(); if (someVar == 1) { console.log('It is 1'); } As a result, you will encounter ...

Route user based on login status using router

I want to set up automatic routing to a login page for users who are not logged in. app.module.ts import { RouterModule, Routes } from '@angular/router'; import { AppComponent } from './app.component'; import { LoginComponent } from &ap ...

Comparison between the version of a particular dependency and the version of its dependent dependency

Imagine a scenario where I have dependency X version 1.0 and dependency Y version 1.0 defined in my package.json. Would there be any issues if Y requires X version 2.0 (as indicated in the package-lock.json) but I continue to use X version 1.0 in my code ...

Using Typescript to import a module and export a sub function

I am currently using mocha for testing a function, but I have encountered an error while running the test file. The structure of my files is organized as follows: server |-test | |-customer.test.ts |-customer.js Here is the content of the customer.js fi ...

The stack property of [object Object] cannot be updated, as it only has a getter method

I can't figure out why I'm receiving this specific error in the Plunker below. Cannot set property stack of [object Object] which has only a getter Access the Plunker here: https://plnkr.co/edit/IP1ssat2Gpu1Cra495u2?p=preview The code causi ...

Enrich your TypeScript code by unleashing the power of enum typing in overloading logical

I have a custom enum called PathDirection that represents different directions export enum PathDirection { LEFT="LEFT"; RIGHT="RIGHT"; }; Within my code, I need to toggle between the two directions. For example: let currentDire ...

Encountered Error: Unknown property 'createStringLiteral', causing TypeError in the Broken Storyshots. This issue is happening while using version ^8.3.0 of jest-preset-angular

When I upgraded to jest-angular-preset ^8.3.0 and tried to execute structural testing with npm run, I encountered the following error: ● Test suite failed to run TypeError: Cannot read property 'createStringLiteral' of undefined at Obje ...

Component fails to navigate to the page of another component

Hello there. I am facing an issue where the button with routelink in the RegistrationComponent is not routing to the page of LogInComponent and I cannot figure out why. Angular is not throwing any errors. Here is the RouteComponent along with its view: im ...

New feature in Next.js 13: Utilizing a string within className

Looking for a way to dynamically generate radio buttons in Next.js using a list of strings? Utilizing Tailwind CSS classes, you can modify the appearance of these buttons when checked by leveraging the peer/identifier classname. But how do you include th ...

Is it possible to update the text within a button when hovering over it in Angular?

I'm looking to update the text displayed inside a button when hovering over it, similar to the examples in these images. I have already implemented the active state, but now I just need to change the text content. <button type="submit" ...

I will not be accessing the function inside the .on("click") event handler

Can someone help me troubleshoot why my code is not entering the on click function as expected? What am I missing here? let allDivsOnTheRightPane = rightPane.contents().find(".x-panel-body-noheader > div"); //adjust height of expanded divs after addi ...

Exciting Angular feature: Dynamic Titles

I am working with an <i> tag <i class="actionicon icon-star" [ngClass]="{'yellow' : data.isLiked}" (click)="Like(data)" aria-hidden="true" title="Liked"></i> In my current set ...

There is only a singular font awesome icon that appears properly based on the conditions set by [ngClass

I'm currently developing a user profile feature that allows users to submit links to their social media accounts. Each account is represented by a clickable icon, and the selection of which icon to display is based on various conditions within [ngClas ...

Is app.component.ts necessary in an Angular 2 project?

Currently diving into Angular 2 and have a burning question on my mind. Do I really need the app.component.ts file in my project? Each of my folders has its own component and template, so I'm debating if the main component is necessary or if I can rem ...

What are the steps to resolve the issue of assigning void type to type ((event: MouseEvent<HTMLDivElement, MouseEvent>) => void) | undefined in a react application?

I'm trying to update the state isOpen to true or false when clicking on a div element, but I keep getting an error with the following code: function Parent() { const [isOpen, setIsOpen] = React.useState(false); return ( <Wrapper> ...