Verify in Typescript if there is at least one value supplied

Looking for a solution:

function takeOneOfOrThrow(firstOptionalVariable : string | undefined, secondOptionalVariable : string | undefined) {
    let result : string; 

    if (!firstOptionalVariable && !secondOptionalVariable) {
        throw new Error('both are undefined'); 
    } 
    result = firstOptionalVariable ? firstOptionalVariable : secondOptionalVariable; 
}; 

Check out the code in this playground: https://tsplay.dev/mxJoxw.

The two variables can be either strings or undefined. The first "if" statement ensures that at least one of them is a non-empty string. So, why does TypeScript give an error stating

Type 'string | undefined' is not assignable to type 'string'
? What would be the correct approach to solve this issue?

Answer №1

The compiler cannot determine the types based on your condition.

Your condition is checking if both variables are undefined, but even if one of them is not undefined, there is no way for the compiler to accurately infer the correct type for them. It wouldn't make sense to assign both as string since that's not what the condition is checking for. The compiler also cannot infer only one as string because it won't know until runtime which one will not be empty. This lack of a clear relationship between variables causes the error when trying to assign to a variable.

One solution is to use the non-null assertion operator as mentioned in another answer. However, it is advisable to avoid using it because if the function body changes and the condition is removed, the compiler won't detect any errors.

A simple alternative is to set a default value if both variables are empty, assuming that the default value won't be used due to the condition:

result = first ?? second ?? ''

Alternatively, you can utilize if/else blocks:

function takeOneOfOrThrow(firstOptionalVariable: string | undefined, secondOptionalVariable?: string | undefined) {
    let result: string;

    if (!firstOptionalVariable && !secondOptionalVariable) {
        throw new Error('both are undefined');
    }
    else if (firstOptionalVariable) {
        result = firstOptionalVariable;
    } else if (secondOptionalVariable) {
        result = secondOptionalVariable
    }
}; 

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

Is there a way to inform TypeScript that an object can only return properties from values found within an array?

I am trying to ensure that the return object from a function in TypeScript only allows keys that correspond to string values present in an array passed as an argument to the function. The returned object should contain a subset of keys from a list of valid ...

What is the process of converting TypeScript to JavaScript in Angular 2?

Currently diving into the world of Angular 2 with TypeScript, finding it incredibly intriguing yet also a bit perplexing. The challenge lies in grasping how the code we write in TypeScript translates to ECMAScript when executed. I've come across ment ...

Looking for a way to toggle the visibility of a dropdown list when clicking on an input in Angular7?

My Angular7 application features a dropdown menu that automatically closes when an item is selected. Additionally, I have implemented functionality to toggle the dropdown open and closed by clicking on an input field. You can view a live example of this be ...

Testing the NestJS service with a real database comparison

I'm looking to test my Nest service using a real database, rather than just a mock object. While I understand that most unit tests should use mocks, there are times when testing against the actual database is more appropriate. After scouring through ...

Form for creating and updating users with a variety of input options, powered by Angular 2+

As I work on creating a form, I encounter the need to distinguish between two scenarios. If the user selects 'create a user', the password inputs should be displayed. On the other hand, if the user chooses to edit a user, then the password inputs ...

Limiting the parameter type in Node.js and TypeScript functions

Currently working on a Node.js project utilizing TypeScript. I'm attempting to limit the argument type of a function to a specific base class. As a newcomer to both Node and TypeScript with a background in C#, I may not fully grasp some of the langua ...

Retrieving the value of an object using an array of keys

Consider the following object: const obj = { A:{ a1:'vala1', a2:'vala2' }, B:{ b1: 'valb1', b2: 'valb2' }, C:{ c1:{ c11:'valc11' }, c2:'valc2' } } We also have an array: const ...

I am experiencing an issue with my date filter where it does not display any results when I choose the same date for the start and end dates. Can anyone help me troub

Having an issue with my custom filter pipe in Angular. When I select the same dates in the start and end date, it doesn't display the result even though the record exists for that date. I've noticed that I have to enter a date 1 day before or ea ...

I'm having some trouble with my middleware test in Jest - what could be going wrong?

Below is the middleware function that needs testing: export default function validateReqBodyMiddleware(req: Request, res: Response, next: NextFunction) { const { name, email }: RequestBody = req.body; let errors: iError[] = []; if (!validator.isEmai ...

Is it possible to utilize instanceof to verify whether a certain variable is of a class constructor type in TypeScript?

I am currently facing an issue with a function that takes a constructor as a parameter and creates an instance based on that constructor. When attempting to check the type of the constructor, I encountered an error. Below are some snippets of code that I ...

Issue deploying serverless: Module '/Users/.../--max-old-space-size=2048' not found

Everything is running smoothly on my serverless project locally when I use sls offline start. However, when I attempt to deploy it through the command line with serverless deploy, I encounter the following error stack. internal/modules/cjs/loader.js:1030 ...

The issue arises when using NestJs with Fastify, as the code does not continue executing after the app.listen()

Greetings everyone, this is my inaugural question on this platform, so please forgive any oversights on my part. I have a query regarding my NestJs application configured to run with Fastify. Unlike Express, the code after the app.listen('port') ...

What are the steps to enable generators support in TypeScript 1.6 using Visual Studio Code?

I have been working with ES6 in Visual Studio Code for some time now, but when I attempt to transition to TypeScript, I encounter errors like: Generators are only available when targeting ECMAScript 6 Even though my tsconfig.json file specifies the ES6 ...

Ways to restrict users from inputting alphabets in TextField using material ui

I've set up a TextField where users can only input positive digits. Currently, I'm using the following onKeyDown event: <TextField label={distanceError} error={!!distanceError} defaultValue={kpoints.distance} on ...

Please come back after signing up. The type 'Subscription' is lacking the specified attributes

Requesting response data from an Angular service: books: BookModel[] = []; constructor(private bookService: BookService) { } ngOnInit() { this.books = this.fetchBooks(); } fetchBooks(): BookModel[] { return this.bookService.getByCategoryId(1).s ...

MaterialUI Divider is designed to dynamically adjust based on the screen size. It appears horizontally on small screens and vertically on

I am currently using a MaterialUI divider that is set to be vertical on md and large screens. However, I want it to switch to being horizontal on xs and sm screens: <Divider orientation="vertical" variant="middle" flexItem /> I h ...

What is the best way to implement a switch case with multiple payload types as parameters?

I am faced with the following scenario: public async handle( handler: WorkflowHandlerOption, payload: <how_to_type_it?>, ): Promise<StepResponseInterface> { switch (handler) { case WorkflowHandlerOption.JOB_APPLICATION_ACT ...

I am attempting to gather user input for an array while also ensuring that duplicate values are being checked

Can someone assist me with the following issue: https://stackblitz.com/edit/duplicates-aas5zs?file=app%2Fapp.component.ts,app%2Fapp.component.html I am having trouble finding duplicate values and displaying them below. Any guidance would be appreciated. I ...

Navigating back to the login page in your Ionic V2 application can be achieved by utilizing the `this.nav

Running into an issue with navigating back to the login screen using Ionic V2. Started with the V2 tabs template but added a custom login page, setting rootPage = LoginPage; in app.components.ts. When the login promise is successful, I used this.nav.setR ...

Return the subclass from the constructor function

class X{ constructor(input: string) { // do things } f() {console.log("X")} } class Y extends X{ constructor(input: string) { // do things } f() {console.log("Y")} } class Z extends X{ con ...