Ensuring Typescript returns the accurate type depending on given parameters

i am working with a code example that looks like the following

interface BaseQuestionType {
  label?: string
}
export type RadioQuestionType = BaseQuestionType & {
  radio: boolean
}
export type TextQuestionType = BaseQuestionType & {
  text: string
}

function test(c: boolean): (RadioQuestionType | TextQuestionType){

  if (c) {
    return {
      radio: true
    }
  } else {
    return {
      text: '11'
    }
  }
}

So we have a function test(c:boolean) which takes in a boolean and returns the corresponding object.

The issue arises when using this function, causing an error

let a = test(true).radio;

In this line of code, TypeScript gives me the following error:

Property 'radio' does not exist on type 'RadioQuestionType | TextQuestionType'.
  Property 'radio' does not exist on type 'TextQuestionType'.(2339)

Although logically correct given ( c is true), how can I convey this to TypeScript? Or is there an alternative approach to address this? Thank you

Answer №1

If you want to achieve the desired behavior, you should consider overloading your function like this:

function test(c: true):RadioQuestionType;
function test(c: false):TextQuestionType;
function test(c: boolean): (RadioQuestionType | TextQuestionType){

You can see an example implementation in this TSPlayground Link

Answer №2

In a manner similar to Nishant's response, but utilizing generics:

function check<T extends boolean>(value: T): T extends true ? RadioQuestionType : TextQuestionType;
function check(value: boolean): (RadioQuestionType | TextQuestionType){
   ...
}

let result = check(true).radio;

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

sidebar that appears upon the initial page load

I'm currently working on implementing a sidebar navigation panel for my website using JavaScript, HTML, and CSS. However, I am facing an issue where the sidebar automatically opens when the page is first loaded, even before clicking on the icon to ope ...

Issue with implementing OpenLayers map in Vue-CLI 3 - troubleshooting needed

I recently incorporated the ol package into my vue-cli project by running npm install ol Unfortunately, despite adding the package, the map is not loading. No errors are displayed and all I see is an empty div in the source result. Here is a snippet o ...

Essential Guide to Binding Events with JQuery

Why is the handler for an event on an element triggering the wrong response? I was expecting the click event of Div1 to display a dialog stating 'div1', but it's showing 'div2' instead. I am new to this and trying to figure out wh ...

Remove a specific date entry from the database using VUE JS and Axios

I am encountering a challenge with Vuejs as I work on a To-Do list. The tasks need to be stored in a MySQL database, and I also want the ability to delete tasks. While I have succeeded in importing and creating data, I'm facing difficulty in deleting ...

Retrieving data from a stored procedure with XSJS and storing it in a variable

I am currently facing a situation where I need to pass a session user as a parameter to a stored procedure in order to retrieve a receiver value. This receiver value needs to be stored in a variable so that I can use it in another function within an xsjs f ...

Vue Google Tag Manager Error: This file type requires a specific loader to be handled correctly

I have integrated "@gtm-support/vue2-gtm": "^1.0.0" in one of my Vue-2 applications, with Vue versions as below: "vue": "^2.5.2", "vue-cookies": "^1.5.4", "vue-i18n": "^8.0.0", "vue-recaptcha": "^1.1.1", "vue-router": "^3.0.1", "vue-scrollto": "^2.17.1", " ...

Alert: Attempting to access an undefined value in an indexed type

I would like to find a way in Typescript to create a hashmap with indexable types that includes a warning when the value could potentially be undefined during a lookup. Is there a solution for this issue? interface HashMap { [index: number]: string; } ...

What steps do I need to take to incorporate Material UI icons into my REACT project?

After reviewing the documentation, I found it somewhat confusing with terms such as "MaterialIcon, SVGIcons, Icons". If you are interested, you can check out the link here. I am looking for a simple explanation of the process from installation to using th ...

When attempting to select an option from the dropdown menu, I encounter an issue where the

My code is not behaving as expected. Whenever I click on the child elements, the dropdown changes to display: none. I am encountering an error when clicking on the input frame and displaying:none. How can I resolve this issue? I would like to be able to ...

Find the most recent date in a file and display the line associated with it

I am working with a document named Application.txt that consists of multiple columns and rows as shown below: ApplNo DocsURL DocDate 4782 www…. 7/28/2003 4782 www…. 11/23/2008 4782 www…. 3/24/2012 5010 www…. 4/5/2003 5010 ww ...

Dividing a string in JavaScript to generate fresh arrays

I am currently dealing with the following string: "ITEM1","ITEM2","ITEM3","ITEM4","ITEM5","ITEM6","ITEM7"~100000000,1000048,0010041,1,1,1,1~100000001,1000050,,2,0,2,1~100000002,1068832,0 ...

Is it possible to utilize dynamic imports in conjunction with a for loop in Next.js?

I often use dynamic import to bring in multiple components efficiently. Is it feasible to use a 'for' loop for this purpose? import dynamic from "next/dynamic"; let Dynamic = []; for (let i = 1; i < 80; i++) { const DynamicComponent = d ...

Generate a nested object dynamically, assign a specific value, and continue adding more objects using pairs of keys and values

Struggling as a newcomer to JavaScript with nesting values of key-value pairs in an object? Take the example below with Basis, where you need to add nested keys and allocate related values from Basis. Each new object should be wrapped in an array within th ...

The Angular application must remain logged in until it is closed in the browser

Currently, my Angular app includes authentication functionality that is working smoothly. The only issue is that the application/session/token expires when there is no user activity and the app remains open in the browser. I am looking for a solution wher ...

Learn how to access nested arrays within an array in React using TypeScript without having to manually specify the type of ID

interface UserInformation { id:number; question: string; updated_at: string; deleted_at: string; old_question_id: string; horizontal: number; type_id: number; solving_explanation:string; ...

What advantages does incorporating SSR with dynamic imports bring?

How does a dynamic imported component with ssr: true differ from a normal component import? const DynamicButton = dynamic(() => import('./Button').then((mod) => mod.Button), { ssr: true, }); What are the advantages of one method over the ...

AngularJS offers a function known as DataSource for managing data sources

During a recent project, I had to convert xml data to json and parse it for my app. One issue I encountered was related to the DataSource.get() function callback in the controller. After converting the xml data using a service, I stored the converted data ...

Tips for sending Json data through a form to a controller and storing it in a database

I am working on a form that contains a sample table with values. The table (id=sampleTbl) has two columns: name and age. My goal is to save this data into my database table named person (id=AI, name, age) when the submitButton (id=idOfButton) is clicked. ...

The closure in question received an undefined Angular parameter

Here is something similar to what I have: $scope.fetchData = function(path, save_to) { $http({method: 'GET', url: 'http://localhost:8001/www-root/' + path}). success(function(data, status, headers, config) { ...

What is the best way to develop a unique animation for every v-card?

Is there a way to customize each animation so that it is specific to the selected v-card? Right now, when one card is clicked, all of them play the same animation. data: () => ({ show: true, images: [ {url:require('@/assets/london. ...