The use of the 'OR' operator with objects is not producing the desired results

When working with two different object types and a function that accepts either one as input, why am I getting an error in TypeScript?

export default function Eingabefeld({
    isText=true,
    children="",
}:(
    {
        isText: true,
        children:string
    } | {
        isText: false,
        children:number
    }
)) { 
    if (isText === true) {
        let data:string = children
        data;
    }else if (isText === false) {
        let data:number = children
        data;
    }
}

I am receiving an error as if the "AND" expression was used to merge the two object types. Why is this happening?

Edit: After further investigation, it appears to be a bug in TypeScript. See: Discriminated union parameter destructuring doesn't work if the fields have defaults

Answer №1

There exist numerous approaches to tackle this issue.

To access the properties, there are two methods:

  1. Simply refrain from destructuring the object
export function Inputfield(props:(
    {
        isText: true,
        children:string
    } | {
        isText: false,
        children:number
    }
)) { 
    if (props.isText === true) {
        let data:string = props.children
    } else if (props.isText === false) {
        let data:number = props.children
    }
}
  1. Destructure it after the if statement
export function Inputfield(props:(
    {
        isText: true,
        children:string
    } | {
        isText: false,
        children:number
    }
)) { 
    if (props.isText === true) {
        let {children} = props
        let data:string = children
    } else if (props.isText === false) {
        let {children} = props
        let data:number = children
    }
}

When applying default values, two different outcomes can be achieved:

  1. Default values for singular properties
type props_type = {
    isText: true,
    children:string
} | {
    isText: false,
    children:number
}
export function Inputfield(_props:(
    Partial<props_type>
)) { 
    const props = {
        isText: true,
        children: "",
        ..._props
    } as props_type

    if (props.isText === true) {
        let data:string = props.children
    } else if (props.isText === false) {
        let data:number = props.children
    }
}

This can also be elaborated with additional conditional assignments if undefined

type props_type = {
    isText: true,
    children:string
} | {
    isText: false,
    children:number
}
function Inputfield(_props:(
    Partial<props_type>
)) { 
    if (_props.isText == undefined) _props.isText = true;
    if (_props.children == undefined) _props.children = "";

    const props = _props as props_type;

    if (props.isText === true) {
        let data:string = props.children
    } else if (props.isText === false) {
        let data:number = props.children
    }
}
  1. A default object
export function Inputfield(props:(
    {
        isText: true,
        children:string
    } | {
        isText: false,
        children:number
    }
)={
    isText:true,
    children:"",
}) { 
    if (props.isText === true) {
        let data:string = props.children
        data;
    } else if (props.isText === false) {
        let data:number = props.children
        data;
    }
}

By using defaults as individual values, not assigning a property will result in the default value being used. When providing a default object, only when no input object is provided, the default will apply.

It is possible to mix together the methods of accessing properties and applying default values as necessary.

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

Enhancing Angular2 authentication with Auth0 for enabling Cross-Origin Resource Sharing

I have been working on implementing user authentication through Auth0. I followed the instructions provided on their website, but I am encountering authentication issues. Whenever I try to authenticate, an error message appears in the console stating that ...

Adjust element sizes in real time with Angular 5

In my current setup, I have 2 interconnected div elements. The left div contains a list of images while the right div displays the details of each image. By clicking on an image in the left div, the right div expands and shows the corresponding information ...

What causes the discrepancy in results between these two NodeJS/Typescript imports?

Within my NodeJS project, I have integrated typescript version 3.2 alongside express version 4.16 and @types/express version 4.16. My development is focused on using Typescript with the intention of transpiling it later on. The guidelines for @types/expre ...

Update the typing of a React component based on a specified prop

Currently, I am in the process of developing a React component called text that will have the ability to change the tag that is rendered. export interface TextProps extends HTMLAttributes<HTMLElement> { children: ReactNode; as?: React.ElementType ...

What is the best way to effectively pass data to a React / NextJS Video component?

I'm currently using a React-based video player that has the following setup: <ReactPlayer playing={true} controls={true} muted={true} loop={true} width="100" height="100" url='videos/330163_SF.mp4' poster="images/ ...

Angular's implementation of a web socket connection

I am facing an issue with my Angular project where the web socket connection only opens upon page reload, and not when initially accessed. My goal is to have the socket start as soon as a user logs in, and close when they log out. Here is the custom socke ...

How can I use Angular 4 typescript to deactivate a button based on the value of a boolean variable?

I am looking to define a function in TypeScript called 'isActive()', which I will then invoke on a button within my HTML file. Additionally, I have already declared a boolean variable named 'isActive'. In this scenario, I have two butto ...

Passing data between Service and Component using Angular Binding

I am attempting to show a loading indicator whenever an Http Request is sent. Although I am using Angular's Http Interceptor, the style of the indicator never seems to update. In my app.component.html, I have included a loading indicator. <div ...

Encountering issues with fs.readFileSync when used within a template literal

For some reason, I am encountering an error when trying to read a file using fs.readFileSync within a Template literal. The specific error message that I'm getting is: Error: ENOENT: no such file or directory, open './cookie.txt' at Obje ...

Save visuals in the typescript distribution folder

Is there a way to properly include images in a Typescript project? I attempted to include the files or directory in tsconfig.json, but it didn't seem to work as expected. "include": [ "src/resources/**/*.png", // <- ...

Can we use a switch statement instead of having multiple @Input()s in Angular?

When passing an attribute into my Angular component like this: <my-component myAttribute></my-component> I aim to modify a variable within the component that controls the CSS properties for width and height. To simplify, I have predefined at ...

*ngif does not control the visibility of Angular Material Progresbar

In my application, the webpage needs to display a progress bar while fetching data from multiple APIs and constructing a PDF document. For this purpose, I am using the jsPDF library to create the PDF. Below is the implementation in my template: <div cl ...

Using asynchronous data in Angular 2 animations

Currently, I have developed a component that fetches a dataset of skills from my database. Each skill in the dataset contains a title and a percentage value. My objective is to set the initial width value of each div to 0% and then dynamically adjust it t ...

The value of 'Boolean' cannot be changed as it is a constant or a read-only property and cannot be assigned

I've been working on creating a TypeScript object to handle read/write permissions in my application, but I'm stuck on an issue with variable assignment that doesn't make sense to me. Any help or guidance would be greatly appreciated. expor ...

Begin the NextJS project by redirecting the user to the Auth0 page without delay

I am new to coding and currently working on a project using Typescript/NextJS with Auth0 integration. The current setup navigates users to a page with a login button that redirects them to the Auth0 authentication page. However, this extra step is unneces ...

How to reference an array from one component to another in Angular 2

Within my AddUserComponent, I have a public array declared like this: public arr: Array<any> = [] This array stores the names of users. Now, I need to access these values in another component called AddTopicComponent in order to display the user&a ...

I'm having trouble with my input - it's not recognizing the text I'm typing or capturing the value. What could be

There seems to be an issue with the input box in my code that uses react hook form. Specifically, when I type into the input field with the placeholder text "Or search for a contact type by name...", the characters do not appear as expected. I have tried ...

Establishing a deadline for Firestore's Node.js library

When using the Firestore Node.js library, I often find that some operations, like fetching a document, can take longer than expected, sometimes even several minutes. I am looking to set a timeout or deadline of around 20-30 seconds for these operations. ...

What could be the reason behind encountering the UnhandledPromiseRejectionWarning error while executing npm build in my serverless application?

I am encountering an issue while attempting to execute npm build on my serverless aws-nodejs-typescript project. I am unsure of how to resolve it. Can someone provide guidance on how to troubleshoot this problem? npm build (node:44390) UnhandledPromiseRej ...

Is it possible to retrieve the signature for every method within a class?

Let's consider a scenario where we have a class defined as follows: class Actions { static FooAction = 'foo' as const; someAction1() { return { type: Actions.FooAction, payload: {a: 1, b:2} }} static BarAction = &apos ...