Automatically identify the appropriate data type using a type hint mechanism

Can data be interpreted differently based on a 'type-field'?

I am currently loading data from the same file with known type definitions. The current approach displays all fields, but I would like to automatically determine which type is applicable without casting the type during runtime. It's not the ideal solution.

I'm unsure if I'm pushing TypeScript too far here and if this logic should instead reside in the loading/parsing process.

Current method

enum MyTypes {
  TypeA = "A",
  TypeB = "B",
}
type IData = {
  type: MyTypes;
  data: IDataAllTypes <---- force the type to be `IDataTypeA` if the type field is `TypeA`
}
type IDataAllTypes = IDataTypeA | IDataTypeB

type IDataTypeA = {
  id: string
  age: number
  foo: string[]
}

type IDataTypeB = {
  id: string
  name: string
  bar: string[]
}

Answer №1

A discriminated union is a type of union where all members share a common field that can be leveraged to define the rest of the type.

To define IData, you can use the following syntax:

type IDataA = {
    type: MyTypes.TypeA,
    data: IDataTypeA
}

type IDataB = {
    type: MyTypes.TypeB,
    data: IDataTypeB
}
type IData = IDataA | IDataB

With this setup, the behavior is as expected:

const testA: IData = { type: MyTypes.TypeA, data: { id: 'qwe', age: 123, foo: ['a'] }}
const testB: IData = { type: MyTypes.TypeB, data: { id: 'qwe', name: 'asd', bar: ['b'] }}

// Type error. Cannot assign type A value with type B properties
const testFail: IData = { type: MyTypes.TypeA, data: { id: 'qwe', name: 'asd', bar: ['b'] }}

Playground

Answer №2

This is the method to achieve it

enum CustomTypes {
  OptionA = "A",
  OptionB = "B",
}

type DataTypeA = {
  id: string
  age: number
  tags: string[]
}

type DataTypeB = {
  id: string
  name: string
  labels: string[]
}

InfoDataA {
  choice: CustomTypes.OptionA,
  information: DataTypeA,
}

InfoDataB {
  choice: CustomTypes.OptionB,
  information: DataTypeB,
}

AllDataTypes = InfoDataA | InfoDataB;

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

Mobile page scroll appears to be disabled due to the Vue range slider

Within my VUE application, I've implemented a range slider component that allows users to view different values as they drag the slider. Everything seems to be functioning correctly, but I've encountered an issue where the mobile version of the p ...

Get a single object from an array with .single method provided by @ngrx

Seeking to retrieve an Observable containing a single object from an array of objects in my store. I aim to utilize the .single operator, which should throw an exception if there is not exactly 1 object present. However, I'm struggling with this as my ...

Unacceptable response from AJAX function

My goal is to extract specific information from this ajax function, such as the thumbnail image and the owner of the image. It seems like the function is not recognizing data.images[i].imgurl and data.images[i].username. AJAX call in ajax.php require_o ...

Deleting a row from a Material UI table: Step-by-step guide

I'm currently working on a CRUD table using React and Material-UI. I have successfully fetched data from an API and displayed it in a table, but now I am facing a challenge with deleting a row. As this is my first project in React, I am seeking guidan ...

Contrasting the disparities between creating a new RegExp object using the RegExp constructor function and testing a regular

Trying to create a robust password rule for JavaScript using regex led to some unexpected results. Initially, the following approach worked well: const value = 'TTest90()'; const firstApproach = /^(?=(.*[a-z]){3,})(?=(.*[A-Z]){2,})(?=(.*[0-9]){2 ...

Having trouble accessing data in Laravel and Vue JS views

I'm currently working on displaying table data in a view using Vue.js and Laravel. Here is what I have attempted so far: This is the comment controller: public function index() { $comment = Comment::Latest()->paginate(10); return new Comm ...

Client-Specific User Portal

Looking for some support on the back end of things. We are in the process of creating a portal where users will be directed to their specific landing pages upon logging in, providing access to files they have signed up for. Our team is exploring the use ...

React Native: Enhance the background with a vibrant stripe of color

I am trying to incorporate a strip of grey in the middle of my white background, but I am encountering an issue where I am unable to input any text inside it. Below is the code snippet I am working with: container: { flex: 1, justifyContent: "cent ...

developed a regular expression to disregard .goutputstream documents

After successfully creating a watcher with chokidar, I encountered an issue when trying to ignore certain files using regex. I am struggling to figure out what went wrong in my code or regex implementation. Below is the snippet of the code: const watcher ...

By setting up a keydown event listener, I am unable to inspect HTML elements by using the F-12 key shortcut in Chrome

Recently, I encountered an issue where adding a keydown event listener in my JavaScript code prevented F-12 from working properly. window.addEventListener("keydown", function (event) { if (event.defaultPrevented){ retu ...

advancement in the $.when function

In an attempt to make an AJAX call utilizing the $.when and $.then functions, I am employing these features to populate a template. During this process, I aim to display a message in a form that states: "Loading data... please wait." I have come across ...

Tips for avoiding parent div click interference in Angular

Working with Angular8, I have a div containing a routelink along with other components including a checkbox. Here's the structure: <div [routerLink]="['/somewhere', blablabla]"> <!--other components that navigate to the ro ...

Can you explain the functionality of this JavaScript registration code?

I am working on an ajax/jquery 1.3.2 based sign up form and I am looking to gain a deeper understanding of how to incorporate jquery into my projects by analyzing the code line by line. Could someone provide a detailed explanation of this code and break d ...

The Ajax PHP file uploader is experiencing technical difficulties

I am currently working on an ajax image uploader that is supposed to work automatically when a user submits an image. However, I've encountered an issue where the uploader does not function as expected when I try to rename the images for ordering purp ...

Angular (2/4) application utilizing custom-named routing within a single page architecture

I'm currently working on an Angular application that consists of a login component and a home component which serves as the main handler for the entire single page application. Additionally, I have three more components named users, each with function ...

Potential issue detected in TypeScript relating to the JQuery.html() method

For example: let $div = $("div"); let $p = $("p"); $div.html($p); This is producing the following error message: Supplied parameters do not match any signature of call target. UPDATE: In plain JavaScript/jQuery, the code is working. An equivalent (in f ...

Incorporate Select2 functionality within the Angular2 application

I'm currently working on incorporating the Select2 plugin into my Angular2 application. Successfully, I have managed to set up select2 and transform my multiple select fields as expected. However, I am now facing a challenge in retrieving the selected ...

Struggling to make fadeIn() function properly in conjunction with addClass

I've been struggling with this issue for quite some time now and I just can't seem to make it work. The JavaScript I'm working on involves using addClass and removeClass to display and hide a submenu element. While the addclass and removeCla ...

Singleton pattern for iFrames sharing the same origin

I have developed a web application that runs on multiple iframes within a parent window, similar to a modified version of GWT. Rather than each individual iframe accessing our backend service separately, I am attempting to have them share the data service ...

Preventing file visibility in Three.js resource directory

Once a user clicks on a specific 3D model, I retrieve it from the server and render it in the browser using three.js. However, there is an issue when the user tries to access a model that is not free - they can easily view and download the STL file by go ...