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

Error TS[2339]: Property does not exist on type '() => Promise<(Document<unknown, {}, IUser> & Omit<IUser & { _id: ObjectId; }, never>) | null>'

After defining the user schema, I have encountered an issue with TypeScript. The error message Property 'comparePassword' does not exist on type '() => Promise<(Document<unknown, {}, IUser> & Omit<IUser & { _id: Object ...

Outputting double columns with Typescript Sequelize associations

I am currently in the process of constructing table models using sequelize along with typescript. Here is an example of one of my models: 'use strict'; import { Model, InferAttributes, InferCreationAttributes, CreationOptional } from 'seque ...

Uh-oh! A circular dependency has been detected in the Dependency Injection for UserService. Let's untangle this web and fix the issue!

Encountering the following error: "ERROR Error: Uncaught (in promise): Error: NG0200: Circular dependency in DI detected for UserService." The auth.component.ts utilizes the UserService and User classes, while the user.service.ts only uses the User class. ...

Unit tests are failing to typecast the Angular HTTP GET response in an observable

I've been delving into learning about unit testing with Angular. One of the challenges I encountered involved a service method that utilizes http.get, pipes it into a map function, and returns a typed observable stream of BankAccountFull[]. Despite ...

Exporting symbols within the same namespace from multiple files in a TypeScript project

I have a typescript module and I am looking to define symbols within the 'aaa' namespace from multiple files. Here is an example of what my code looks like: a.ts: export namespace aaa { export const a = "a"; } b.ts: export namespac ...

What's the deal with the `return of ()` syntax?

Just came across this piece of code: https://i.sstatic.net/JZXP5.png Code snippet in typescript. The first line looks like: ... return of (true); Can someone explain this syntax to me? ...

Creating a Robust Next.js Build with Tailor-Made Server (Nest.js)

I'm in need of assistance with compiling/building my project using Next.js while utilizing a custom server. Currently, I have integrated Nest.js (a TypeScript Node.js Framework) as the backend and nested Next.js within it. The integration seems to be ...

What is preventing typescript from inferring these linked types automatically?

Consider the following code snippet: const foo = (flag: boolean) => { if (flag) { return { success: true, data: { name: "John", age: 40 } } } return { success: false, data: null } ...

Tips for calculating the total sum of inner object property values using JavaScript, TypeScript, or Angular 5

What is the total sum of successCount values in the given array object? var successCount;//I want count of all successCount attributes from the below object var accordianData = [ { name: "Start of Day", subItemsData: [ { title: " ...

Error code 2769 in Typescript occurs when attempting to transfer process information to the data state in order to utilize it within a modal

I'm encountering an issue while trying to pass a process to a setData state from a .map function in order to display it on a modal. The error message I'm receiving is: "No overload matches this call. Overload 1 of 2, '(props: { compone ...

Angular TypeScript test checking file size with Jasmine

Seeking optimal method for testing File size during input type="file" change event. Currently, my test specification appears as follows: it('attach file with too large size', () => { const file: File = { name: 'filename', ...

Specify the object key type when using a `for-in` loop

My current situation involves an object type: interface ShortUrlParam { openid: string; avatar: string; nickname: string; } const param: ShortUrlParam = { openid: 'abc123', avatar: '', nickname: 'wenzi&apo ...

Is it necessary to compile the ngfactory files during Angular 2 AOT compilation?

I've noticed an interesting behavior when compiling my Angular 2 application with `ngc`. During the first run, it generates the `.ngfactory.ts` files for each component but only compiles the TypeScript to JavaScript for other files. This results in no ...

Error: An unexpected character (.) was encountered | Building with npm has failed

When executing "npm run build", I encounter an error with the unexpected token (.) related to object values. Can someone assist me in resolving this issue? I am using tsc build for a react npm library. It seems like there might be a configuration problem ...

Is it possible to pass a variable to a text constant in Angular?

In my constant file, I keep track of all global values. Here is the content of the file: module.exports = { PORT: process.env.PORT || 4000, SERVER: "http://localhost:4200", FAIL_RESULT: "NOK", SUCCESSFUL_RESULT: "OK ...

Unable to prolong TypeScript document

As I develop a drag and drop interface, upon dropping a file, the native File is retrieved. To enhance this interface with additional information, I decided to explore various approaches. In my initial attempt, I utilized: interface AcceptedFile extends ...

Is it possible to remove a complete row in Angular 2 using Material Design

JSON [ { position: 1, name: 'test', value: 1.0079, symbol: 'HHH' }, { position: 2, name: 'test2', value: 4.0026, symbol: 'BBB' }, { position: 3, name: 'test3', value: 6.941, symbol: 'BB' }, ...

What is the best way to retrieve the value of an input field in React when incorporating Material UI components?

I am working with a few radio input components that have been imported from material Ui react. Each radio input is wrapped in a FormControlLabel component. <FormControlLabel onClick={checkAnswerHandler} value={answer} control={<Radio color=&quo ...

Child component experiencing issues with Materialize Pagination and Sorting functionalities not functioning

New to materialize pagination and currently working on the hierarchy below: app modules > list > list.component app.component Implemented a sample code example in app.component which worked perfectly. However, encountered issues when trying to imp ...

Is it possible to identify and differentiate objects based on their interface types in JavaScript/TypeScript?

Incorporating a library that defines the following interfaces: LocalUser { data { value: LocalDataValue }, ...various other methods etc... } RemoteUser { data { value: RemoteDataValue }, ...various other methods etc... } A User is then ...