Generating dynamic types based on conditions in TypeScript

I have a starting type called BaseType, and I am looking to dynamically extend it by combining multiple types based on a discriminating value. For example, if the discriminating value is set to "foo" or "bar", I would create separate types like FooType and BarType with specific properties.

Essentially, I want the flexibility to discriminate between various types as needed.

For instance:

interface BaseType {
  base: string;
}

interface FooType {
   foo: boolean;
   fooType: string;
}

interface BarType {
   bar: boolean;
   barType: number;
}

interface BazType {
  baz: boolean;
  bazType: boolean;
}

// The following examples are valid only when discriminating to one type.
myFunc({
   base: "",
   foo: true,
   fooType: "", // <== An error should occur if this is missing.
});

myFunc({
   base: "",
   bar: true,
   barType: 2, // <== An error should occur if this is missing.
});


// However, I aim to discriminate among multiple types using a similar approach.
myFunc({
   base: "",
   foo: true,
   fooType: "", // <== Error if missing when foo is true.
   bar: true,
   barType: 2, // <== Error if missing when bar is true.
});

// Another scenario
myFunc({
   base: "",
   bar: true,
   barType: "", // <== Error if missing when bar is true.
   baz: true,
   bazType: false, // <== Error if missing when baz is specified.
});

// This can exclusively discriminate to only one type at a time, not both simultaneously.
type AllType = FooType | BarType | BazType;

Answer №1

It appears there may be some uncertainty regarding the specifics of your request, but it seems achievable by utilizing type unions and boolean literals.

For example, I successfully implemented the following approach. In this scenario, I assumed that you require fooType when foo is true and barType when bar is true. Additionally, I presumed that complete optional data for both foo and bar is desired...

Does this proposed solution provide a starting point for your needs?:

// A utility type
type TrueFalseShapes<Optionals, BoolName extends string, T={}> = (T & {[Key in BoolName]: true} & Optionals) | (T & {[Key in BoolName]: false} & Partial<Optionals>);

// Usage example:
type BarType = TrueFalseShapes<{barType: string}, "bar">;
type FooType = TrueFalseShapes<{fooType: string}, "foo", {base: string}>;
type BigType = FooType & BarType;
const a: BigType = {base: 'hi', bar: false, foo: false};
const b: BigType = {base: 'hi', bar: true, barType: "bar string", foo: false};

Edit: Refined the suggestion into a single utility type for clarity.

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

Making changes to a property within a class does not automatically reflect those changes in the corresponding view

In my Typescript (.ts) file, this is the code I have: private today: Date = new Date(); And this is the corresponding HTML: <span [innerText]="today | date:dateFormat"></span> Everything displays perfectly, showing 22nd May. Now, I&apos ...

In Next.js with Typescript, an error occurs when trying to access the property 'menu1' on a variable that is either a string or an instance of AbstractIntlMessages. The error specifies that the property 'menu1' does not exist on type 'string'

I'm currently utilizing Nextjs, typescript, and next-intl in my project. Within my layout.tsx file, I have the following code snippet: import {NextIntlClientProvider} from 'next-intl'; import {getMessages} from 'next-intl/server'; ...

How to correctly type socket events when developing a customized useSocket hook in TypeScript?

Both my socket server and socket client are set to listen for a specific range of events. Below are the definitions for these socket events: import { Server } from "socket.io"; import { Socket } from "socket.io-client"; import { Disconn ...

Angular: Identifier for Dropdown with Multiple Selection

I have recently set up a multi select dropdown with checkboxes by following the instructions provided in this post: https://github.com/NileshPatel17/ng-multiselect-dropdown This is how I implemented it: <div (mouseleave)="showDropDown = false" [class. ...

Angular view not showing dates retrieved from MySQL database

Currently, I am experimenting with Angularjs alongside TypeScript to create a simple to-do list as a web page for practice and fun. Below is my controller that interacts with the database and stores the objects: module app.ToDo { class ToDoCtrl { ...

Angular Routing can be a powerful tool for managing multiple article posts in an efficient and organized way

I am in the process of building a website with Angular that features numerous articles. Whenever a user clicks on an article, I want it to navigate to a new URL using routing. To achieve this, I have created a new Article component and here is how my app- ...

What is the best way to display multiple items on a single page using the Ant Design (NG-Zorro) carousel component?

Hey there, I'm looking for a way to display multiple items per page using the ant design (NG-Zorro) carousel. I found some information on their website here: What I'm aiming for is to have something like this - Multiple Items If you have any i ...

The function is not operational while executing addEventListener

I'm encountering some bugs in my Angular 1.5 project with TypeScript. I'm trying to retrieve the scrollTop value from the .uc-card element. public container = document.querySelector(".uc-card"); In my $onInit, I have: public $onInit() { this ...

Discover the secret to creating an efficient TypeScript function that offers autocomplete with enum values

I'm attempting to achieve a scenario similar to the code below: enum Color { RED="RED", GREEN="GREEN", BLUE="BLUE" } function setColor(color:Color) { } However, when I attempt to call the function like this: setColor("RED"), I encounter the ...

Configuring babel-plugin-styled-components with TypeScript in a create-react-app environment

Currently, we are working on integrating the babel-plugin-styled-components into our setup, which is based on typescript and create-react-app. Our main goal is to improve the debugging experience, but we are facing challenges in achieving this. We want to ...

Merge mocha with Typescript, and include the watch feature

For my project, I have set up mocha to test my Typescript code. The issue arises when running the command: mocha ts/test --compilers ts:typescript-require Every time I make a change, it fails with an error message like this: error TS2307: Cannot find mo ...

Typescript support on Emacs

"Is there a way to enable Typescript syntax highlighting in Emacs?" I have been struggling with this for quite some time. Using Emacs 24 on an Ubuntu Virtualbox VM, I can't seem to get package-refresh-contents to work as it just hangs on "Contacting ...

Creating a generic hashmap that can accept dynamic keys and an array of type T

In my attempt to create a robust typing interface for a hashmap in typescript, The hashmap consists of a key with a dynamic string name, and a values array containing a Generic type. I attempted to define the interface as follows: export interfa ...

Creating sophisticated TypeScript AngularJS directive

Recently, I came across a directive for selecting objects from checkboxes which can be found at this link: The issue I'm facing is that we are using TypeScript and I am unsure of how to implement the directive in TypeScript. From what I understand, ...

Issue with redirecting to another link in Angular routing

After numerous attempts, I finally managed to configure the adviceRouterModule correctly. Despite extensive research and Google searches, I couldn't quite crack it. Here is the configuration for my AdviceRoutingModule: const adviceRouters: Routes = ...

Ignore TypeScript errors when using TSNode with Mocha by forcing the compiler to emit code despite errors and having TSNode execute the emitted code

Below is a code snippet where the function test2 is invalid, but it should not affect testing of function test1: export function test1(): boolean { return true; } export function test2(): number { return "1"; } Test: import { assert as Assert } fr ...

Deactivating Bootstrap Modal in Angular

Looking for advice on managing a Bootstrap Modal in Angular 7 I have a Form inside a Bootstrap Modal that I need to reset when the modal is closed (by clicking outside of it). Despite searching on Google, I haven't been able to find a solution. Any ...

Asynchronous retrieval of reference value from Firebase Firestore in ReactJS

Encountering a peculiar bug in TypeScript-JavaScript where I have a Model class in TypeScript and a ReactJS Component in JS. The issue arises when dealing with a list of Promo Objects, each containing a "_listCompte" property which holds a list of Compte O ...

The element property cannot be found on the specified Element type in ANGULAR

Unable to resolve error in ng build --prod after successful execution of ng serve: Error - Property 'element' does not exist on type 'Element'. https://i.sstatic.net/l3KX4.png Edit-depart.html <form #employeeForm="ngForm& ...

Anticipating the resolution of promises and observables in Angular 2

Within my accountService module, there is a dialog prompt that requests the user's username and password, returning a promise. If the user clicks on close instead of dismissing the dialog box and the validators require the input data before allowing t ...