Issue reported: "Usage of variable 'someVar' before assignment" ; however, it is being properly assigned before usage

This piece of code showcases the issue:

    let someVar: number;

    const someFunc = async () => {
      someVar = 1;
    }

    await someFunc();

    if (someVar == 1) {
      console.log('It is 1');
    }

As a result, you will encounter the error:

Variable 'someVar' is used before being assigned

However, it seems perplexing as to why the variable would not be assigned.

I am aware that I could retrieve the value from someFunc and assign it to someVar within that function. My query is not about fixing this code but understanding why the error occurs.

(The actual issue stems from the callback function passed to mongoose.connection.transaction, limiting direct access to its return value - necessitating assignment from within the function).

(TS 4.5.4, node 16.20.0)

PLEASE NOTE: This is NOT a duplicate of Variable 'test' is used before being assigned - Typescript

The solution in that instance pertains to assigning properties of an object before initializing the object itself. This explanation diverges from the current discussion besides the shared error message.

Scenario:

let someVar;

await mongoose.connection.transaction( async (session) => {

//specific mongoose operations occur here.

someVar = await SomeModel.findByIdAndUpdate(id, {newThing});

}

if(someVar)... //error!

While I acknowledge that returning the value and subsequent assignment may resolve the simplified example, the requirement of operating within a callback limits straightforward access to the return value.

Why not simply declare and utilize someVar within the mongoose transaction to circumvent side effects? The challenge arises when attempting to send it as a response leading to issues like: Mongoose transaction gives Attempted illegal state transition from [TRANSACTION_COMMITTED] to [TRANSACTION_ABORTED] when Express response sent inside

Answer №1

Typescript has its limitations when it comes to following control flow and inferring types. It cannot execute the entire program and determine types automatically.

When TypeScript checks if a variable was assigned before use, here is what it looks for:

  • An uninitialized variable let someVar: number;
  • Then a function of type () => Promise<void> is called
  • Finally, you try to use someVar without assigning it a value in this scope.

Declaring that a function has side effects which impact the types in a scope is not possible. A "side effect" refers to mutating a value outside of its own scope.

Without understanding your specific objective, it's challenging to provide a solution. However, returning the value instead might be a better approach in this situation to ensure proper assignment within the correct scope.

For example:

async function foo() {
  let someVar: number;

  const someFunc = async () => 1;

  someVar = await someFunc();

  if (someVar == 1) { // works fine
    console.log('It is 1');
  }
}

See playground

This method is generally preferable as minimizing function side effects is beneficial when feasible.


If you are unable to access the return value, initializing the variable becomes necessary since TypeScript cannot analyze your functions as desired.

Initialize to undefined and then narrow down the type after the function runs to confirm it was set correctly.

async function foo() {
  let someVar: number | undefined; // include undefined in the type here

  const someFunc = async () => {
    someVar = 1
  };
  
  await someFunc();
  if (someVar === undefined) throw new Error("someVar was not set")

  // type of `someVar` now is `number`
  
  if (someVar == 1) {
    console.log('It is 1');
  }
}

See Playground


You can utilize the ! type operator to indicate that the variable may be undefined, but each time it is accessed, assume it exists.

async function foo() {
  let someVar!: number; // note the ! here

  const someFunc = async () => {
    someVar = 1
  };
  
  await someFunc();

  if (someVar == 1) {
    console.log('It is 1');
  }
}

This is not ideal as it reduces the type safety of your code. It means that the compiler will not check if the assignment occurred, leading to potential runtime errors instead of compile-time errors if the assignment fails for any reason.

Therefore, consider this as a last resort option.

See Playground

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

The Redux Toolkit slice and TypeScript were not in agreement: it was expecting 0 arguments, but received

Recently, I encountered an issue with my slice code: const investment = createSlice({ name: 'investments', initialState, reducers: { getInvestmentsRequest(state) { state.investments.status = RequestStatuses.loading; }, } }) ...

"Emphasizing the Html.ActionLink menu for improved user navigation and

Currently, I am facing an issue with my menu. I want to clear previously visited links while keeping the current one styled as a:visited in CSS. Although I have attempted to achieve this, unfortunately, the code is not functioning properly. Here is what I ...

Styling is lost in FancyBox popup when loading Partial View

I've been attempting to incorporate a partial view into my MVC project using fancybox. It seems to be loading the content correctly, mostly anyway, as it tends to cut off part of the page and loses all styling from the view upon loading. Even after i ...

In the readmore.js script, position the "readmore" link within a div instead of outside of it

I have added annotations that vary in length, so I am looking to integrate the readmore.js plugin. To ensure uniform sizing for all annotations (even empty ones), I need to set a minimum height for the div container. <annotation> <div style="wi ...

Issue: failure of child element - the provided path is incorrect: "users/[object Object]", when implementing Firebase with Next.js

Having trouble with the identityNumber variable, which is giving an error message stating that a string is required. However, my identity number is already a string. Any assistance would be greatly appreciated. Additionally, the aim is to make the identity ...

Submit the scaled-down form image to the server

When attempting to upload a resized image to the server, an error stating "Required MultipartFile parameter 'file' is not present" occurs. Interestingly, this error only appears when trying to upload the resized image, as uploading the original f ...

Jstree's select_node function is failing to trigger

I am having an issue with the select_node.jstree function not firing properly. Below is the code snippet: $(document).ready(function () { //$("#MySplitter").splitter(); setupSplitter(); $("#divJsTreeDemo").jstree({ "themes": { "theme": "d ...

How to personalize your Fullcalendar event tooltips with custom profile images

I recently integrated the Fullcalendar plugin by Adam Shaw with Bootstrap 3 on my website to display events created by users. Each event has a popover script that provides additional information when clicked. One feature I would like to add is displaying ...

When state is updated, the component is re-rendered multiple times

I am working on setting the state in componentDidMount lifecycle method to verify data from local storage. Depending on whether the data exists in local storage, I either redirect the user to the login page or keep them on the dashboard. Is there a way to ...

How to use the route.navigate() method in Angular 9 to open a URL in a new tab with a query string

When a button is clicked within a table in our application, I have to open a new tab with details of a specific record from the table. Currently, the code I am using navigates to a new URL and uses resolvers to fetch data from the backend on the new page. ...

Choose all the checkboxes that use Knockout JS

Struggling with implementing a "select all" checkbox feature as a Junior developer on a complex project utilizing knockout.Js and Typescript. I can't seem to figure out how to select all existing checkboxes. Here is the HTML: <td> <inp ...

The dropdown menu in the navigation bar is overlapping with the datatable, creating a transparency effect

Working on a website layout that features a navbar at the top and a datatable below. However, when hovering over the navbar to reveal subitems, I notice a transparency issue where the navbar overlaps with the datatable. Below is a simplified version of my ...

Extract the content from a <Span> element without specifying its ID

Is there a way to make it so that when a user clicks on an HTML tag, the text is copied to their clipboard? I also need to ensure that this functionality does not apply to a specific tag ID/name as I am unable to add those to my span. Is there a way to aut ...

Issue persists with Angular 2 *ngFor functionality even after successfully importing CommonModule

After creating a feature module using the CLI, I imported the common module as shown below: import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { HomeComponent } from './home/home.compo ...

Tips for resolving undefined error handling in node.js

const fileSystem = require('fs'); const fileName = './prices.json'; const file = require(fileName); const price = require('./prices.json'); const fileName = './prices.json'; if(tmd = message.match(/^!change max ...

React - Parent Component not successfully passing Ajax data to Child Component

I have a parent component and a child component. I am using the fetch method within the componentDidMount() callback to retrieve data from an API and then set the state with key items to that data. The intention is for this data to be passed down to the ch ...

I have noticed that the baseline of a Span element has shifted after updating my Chrome browser to a version that begins with

Once I updated to chrome Version 108.0.5359.94 (Official Build) (64-bit) from 107.0.5304.87 (Official Build) (64-bit), the behavior of the span element changed drastically. It shifted its baseline when multiple spans were stacked on top of each other. Exp ...

Is it possible to obtain a return value from Electron's webContents.executeJavaScript when NodeIntegration is disabled?

Is there a way to retrieve a return value without using NodeIntegration in Electron, similar to ipcRenderer when it's enabled? ...

Every time the page is refreshed, the value stored in React localStorage gets

After adding a new item to the list, the local storage gets updated. However, upon page refresh, I noticed that the key remains but the value is reset to an empty array. import { useState, useEffect } from 'react'; function App() { const [data ...

Unable to establish React API communication on cloud-based IDE for MERN Stack development

Exploring the MERN stack through this informative tutorial: https://medium.com/@beaucarnes/learn-the-mern-stack-by-building-an-exercise-tracker-mern-tutorial-59c13c1237a1 I've opted to use goorm IDE, a cloud platform similar to cloud 9 IDE. As I pro ...