There seems to be an issue with the type error regarding the return of the mysql2/promise

As I delve into using the mysql2/promise library with Typescript, I've encountered a puzzling issue regarding the return type of the query method. Despite my best efforts, I can't seem to resolve an error in my code.
Here is a snippet from my code:

import * as mysql from "mysql2/promise";

let mysql_connection: mysql.Connection = await mysql.createConnection({
   //Some options here.
});

let backend_mysql_res: [(mysql.RowDataPacket[][] | mysql.RowDataPacket[] | mysql.OkPacket | mysql.OkPacket[] | mysql.ResultSetHeader), mysql.FieldPacket[]] = await mysql_connection.query(`SELECT * FROM data.table ORDER BY time DESC LIMIT 1`);

//The error occurs at this line. 
console.log(backend_mysql_res[0][0]);

The error message related to backend_mysql_res[0][0] towards the end of the provided code reads as follows:

TS7053: Element implicitly has an 'any' type because expression of type '0' can't be used to index type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader'.   Property '0' does not exist on type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader'.

This error message references type '0', but what exactly does type '0' represent? Is it supposed to denote numbers?
I find myself stumped by this problem and unable to come up with a solution.

Can anyone shed light on the correct types associated with the response of the query method within mysql2/promise? Moreover, the extensive type declaration in let backend_mysql_res ... was advised by the IDE. However, I believe it could be streamlined. Is there a way to simplify the code effectively?

I'm fairly new to learning Typescript, so any assistance would be greatly appreciated.
Please lend me your expertise.

Answer №1


I have implemented a custom function that can handle single queries effectively. However, I am still in the process of enhancing it to support multiple queries.

To begin with, I created a wrapper for the MySQL connection query in TypeScript as shown below. Suggestions for improvement are welcome.

import {
  createPool
} from "mysql2/promise";
var pool = createPool({
  waitForConnections: true,
  connectionLimit: 10,
  host: process.env.DBHOST,
  port: parseInt(process.env.DBPORT),
  user: process.env.DBUSER,
  password: process.env.DBPASSWORD,
  database: process.env.DB_NAME,
  multipleStatements: true,
  connectTimeout: 30000,
});
export const fireQuery = async <
  T extends RowDataPacket[][] | RowDataPacket[] | OkPacket | OkPacket[] | ResultSetHeader > (QUERY: string, PARAMS: any[] = []): Promise < T extends RowDataPacket[][] | RowDataPacket[] | OkPacket | OkPacket[] | ResultSetHeader ? T : RowDataPacket[][] | RowDataPacket[] | OkPacket | OkPacket[] | ResultSetHeader > => {
    const connection = await pool.getConnection();
    try {
      console.log("starting transaction...", QUERY, PARAMS);
      await connection.beginTransaction();

      console.log("running query...");
      let queryResult = await connection.query <
        T extends |
        OkPacket |
        ResultSetHeader |
        RowDataPacket[] |
        RowDataPacket[][] |
        OkPacket[] ?
        T : OkPacket | ResultSetHeader | RowDataPacket[] | RowDataPacket[][] | OkPacket[] > (QUERY, PARAMS);
      console.log("committing transaction...");
      await connection.commit();
      console.log("transaction committed.");
      return queryResult[0];
    } catch (error) {
      Sentry.captureException(error);
      connection.rollback();
      console.error("an error occurred:", error);
      throw error;
    } finally {
      connection.release();
    }
  };

This code snippet can be utilized as demonstrated below.

For Single query

export interface ISelectQueryInterface extends RowDataPacket {
col1: string;
col2: number;
col3: boolean;
}

const getUserResult = await fireQuery<UserRDataType[]>("select col1, col2, col3 from table where mobileNo = ?", [data.mobileNo])

For handling multiple queries, a workaround is employed by initially specifying the data type as 'any' and then providing the schema tailored to our requirements.

export interface ISelectQueryInterface1 extends RowDataPacket {
    col1: string;
    col2: number;
    col3: boolean;
}
export interface ISelectQueryInterface2 extends RowDataPacket {
    col4: string;
    col5: number;
    col6: boolean;
}
export interface ISelectQueryInterface3 extends RowDataPacket {
    col7: string;
    col8: number;
}
const output: [ISelectQueryInterface1[], ISelectQueryInterface2[], ISelectQueryInterface3[]] = await fireQuery<any>("select col1, col2, col3 from table where mobileNo = ?;select col4, col5, col6 from table where email = ?;select col7, col8 from table;", ["1234567890", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ff9e9d9c9bbf98929e9693d19c9092">[email protected]</a>"]);

Answer №2

While it may not be the perfect solution, one approach is to utilize the following code snippet:

let backend_mysql_res: any = await mysql_connection.query(`SELECT * FROM data.table ORDER BY time DESC LIMIT 1`);

This will grant you access to the necessary fields. To view the results, execute:

console.log(backend_mysql_res)

It can provide insight into the outcome.

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

How can you retrieve the preceding sibling using an Angular directive?

Currently, I am utilizing ELEMENTREF to interact with the DOM via Renderer2. Allow me to provide a simple example: import { Directive, Renderer2, ElementRef } from '@angular/core'; @Directive({ selector: '[appHighlight]' }) export c ...

What is the best way to duplicate a Typescript class object while making changes to specific properties?

I have a Typescript cat class: class Kitty { constructor( public name: string, public age: number, public color: string ) {} } const mittens = new Kitty('Mittens', 5, 'gray') Now I want to create a clone of the inst ...

Unable to destructure props and assign them to a react-bootstrap component

I recently installed react-bootstrap and I am looking to customize the default buttons in my project. My goal is to simplify the button creation process by just using <Button> without specifying a variant option for most buttons. import * as bs from ...

The attribute 'close' is not present in the 'Application' data type

My approach to importing expressjs looks like this: import { Request, Response, Application, Router } from 'express'; const app: Application = require('express')(); In my typings.json file: "express": "registry:npm/express#4.14.0+20 ...

Attention Needed - Certain vulnerabilities necessitate manual review for resolution

npm audit === Security Report from npm audit === # You have 1 vulnerability that can be resolved by running `npm update terser-webpack-plugin --depth 3` Severity Issue ...

What is the correct way to effectively integrate react-hook-form with redux and typescript?

After tirelessly searching for a comprehensive guide that could demonstrate all these requirements in one example, I eventually resorted to brute force to make something functional. However, I am well aware that this approach is not the correct way to achi ...

The return type is not undefined but the switch covers all possibilities

I'm struggling to understand the issue with this simple example interface List { "A": false, "B": false, } // The function is missing a return statement and its return type does not include 'undefined'.ts(2366) / ...

Attempting to revert the imported module back to its initial/default mock configuration

When working on my test file, I utilize a folder named mocks which contains various exported functions. Most of the time, I rely on the mocks folder to perform all necessary tasks. However, there is one scenario where I need to adjust the return value to a ...

Angular HTML Component Refactor causes compatibility issues with BS4 classes

Currently, I am working on Angular components and I have a specific section that I would like to refactor into a separate component for reusability. Initially, when the HTML block with only Bootstrap 4 classes is placed in the parent component, the user in ...

The feature of "compile on save" is not functioning properly in my current Angular project

Yesterday I used the angular cli (ng new my-app) to create a new project, but unfortunately the "compile on save" option is not functioning properly. Interestingly, I have two projects on my computer and this feature works fine for one of them but not for ...

How to generate an array within a TypeScript extension function

As I was working on creating an extension method using typeScript, the main goal was to establish a static or normal variable within the method. The ServiceCollector method was invoked three times in order to send and store data or objects in an array. B ...

Set up a global variable for debugging

Looking to include and utilize the function below for debugging purposes: export function debug(string) { if(debugMode) { console.log(`DEBUG: ${string}`) } } However, I am unsure how to create a globally accessible variable like debugMode. Can this be ...

Type to match the data type of the enum, not strictly one specific value

enum X { A = 'x', B = 'y' } type A<T> = { prop1: T prop2: X } let r:A<X> = { prop1: X.A, prop2: X } What specific type must be assigned to A.prop2 in order for only X and no other item to also be assigned to i ...

TypeScript focuses on checking the type of variables rather than their instance

Is there a way to pass a type (not an instance) as a parameter, with the condition that the type must be an extension of a specific base type? For example abstract class Shape { } class Circle extends Shape { } class Rectangle extends Shape { } class ...

When accessing from the frontend (Angular), the User.FindFirst(ClaimTypes.NameIdentifier) method does not return any values

I'm encountering a new issue - just as the title suggests. I've managed to identify where the problem occurs but I'm unable to resolve it. Let's start from the beginning. In the backend (ASP.NET 3.0), I have a class AuthController with ...

Error in ThreeJS: Unable to execute material.customProgramCacheKey

I encountered an issue TypeError: material.customProgramCacheKey is not a function The error pops up when I invoke the function this.animate(). However, no error occurs when the URL is empty. Where could this error be originating from since I don't ...

Is there a way to update the data on a view in Angular 9 without the need to manually refresh the page?

Currently, I am storing information in the SessionStorage and attempting to display it in my view. However, there seems to be a timing issue where the HTML rendering happens faster than the asynchronous storage saving process. To better illustrate this com ...

Uploading images using multipart in react is causing an error and cannot be completed

Trying to upload images in the database using multipart is causing an error from the API saying 'Files can't be uploaded". Checking the API in postman shows it is working fine there. There seems to be an issue with my code, but I can't ...

Is there a way to simultaneously filter by two attributes using mat-select-filter in Angular?

I have integrated the mat-select-filter library in my Angular project, but I am facing an issue with the displayMember filter. Currently, it only filters by code, but I would like it to also filter by name simultaneously. Is there a way to achieve this u ...

What role does typescript play in this approach?

test.js const testList = [1, 2, 2, 4, 5, 2, 4, 2, 4, 5, 5, 6, 7, 7, 8, 8, 8, 1, 4, 1, 1]; const lastIndex = testList.findLastIndex((e:number) => e === 100); // Property 'findLastIndex' does not exist on type 'number[]'. Did you mean ...