Is it possible to remove generic T in typescript if the mysql result value is an array but generic T is not an array?

type User = {
  name: string
  email: string
}

This is the code snippet,

import type { PoolConnection, RowDataPacket, OkPacket } from "mysql2/promise";

type dbDefaults = RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[];
type dbQuery<T> = T & dbDefaults;

type FlattenIfArray<T> = T extends (infer R)[] ? R : T;

function isFlattenArray<T>(rows: any[]): rows is T[] {
  return rows.length < 1;
}

// eslint-disable-next-line consistent-return
export async function queryWrapper<T>(
  { query, values }: { query: string; values?: string[] },
  conn: PoolConnection
): Promise<T | undefined> {
  try {
    await conn.beginTransaction();
    const [rows, _] = await conn.query<dbQuery<T>>(query, values || undefined);
    await conn.commit();

    if (isFlattenArray<FlattenIfArray<T>>(rows)) {
      return rows;
    }

    return rows;
  } catch (error) {
    await conn.rollback();
  } finally {
    conn.release();
  }
}

The Mysql code returns only the array

There is no issue with User[]. However, when using User, I want to eliminate the array structure.

So I tried using this code, but it did not produce the desired result. What steps should I take?



I have provided additional clarification.

const result = queryWrapper<User>(query, values, conn)

When utilizing user, the output appears as below.

[
  {
   name: "user-name",
   email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="daafa9bfa89abdb7bbb3b6f4b9b5b7">[email protected]</a>"
  }
]

However, I desire it to be displayed like this.

{
 name: "user-name",
 email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="700503150230171d11191c5e131f1d">[email protected]</a>"
}

Answer №1

I will respond on my own.

type dbDefaults =
  | RowDataPacket[]
  | RowDataPacket[][]
  | OkPacket
  | OkPacket[]
  | ResultSetHeader;

type Query = { query: string; values?: any[] };

type QueryFunction<T = any> = () => Promise<[T & dbDefaults, FieldPacket[]]>;

type AlwaysArray<T> = T extends (infer R)[] ? R[] : T[];
// eslint-disable-next-line consistent-return
export async function queryTransactionWrapper<T = any>(
  queries: QueryFunction[],
  conn: PoolConnection
): Promise<[AlwaysArray<T>, FieldPacket[]][] | undefined> {
  try {
    await conn.beginTransaction();
    // await conn.query("START TRANSACTION;");

    const executedQueries = await Promise.all(
      queries.map((query) => {
        return query();
      })
    );

    // await conn.query("COMMIT;");
    await conn.commit();
    return executedQueries;
  } catch (error) {
    logger.error(colors.blue(JSON.stringify(error)));
    await conn.rollback();
  } finally {
    conn.release();
  }
}

export function findOne({ query, values }: Query, conn: PoolConnection) {
  return function () {
    return conn.query<RowDataPacket[]>(query, values);
  };
}

export function find({ query, values }: Query, conn: PoolConnection) {
  return function () {
    return conn.query<RowDataPacket[]>(query, values);
  };
}

export function update({ query, values }: Query, conn: PoolConnection) {
  return function () {
    return conn.query<ResultSetHeader>(query, values);
  };
}

export function insert({ query, values }: Query, conn: PoolConnection) {
  return function () {
    return conn.query<OkPacket>(query, values);
  };
}

when calling findOneUser

async findByEmail(email: string): Promise<IUser | undefined> {
    const conn = await this.mysql.getConnection();
    const query = `Select * FROM ${USER_TABLE} WHERE email=?`;

    const findUserQueryFunction = findOne({ query, values: [email] }, conn);

    const executedQueries = await queryTransactionWrapper<IUser>(
      [findUserQueryFunction],
      conn
    );
    if (!executedQueries) {
      throw new Error();
    }
    const [[rows]] = executedQueries;

    return rows[0];
  }

if <IUser[]>, findByEmail will return rows else it will return rows

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

Tips on preventing the occurrence of double encoding in raw JSON output from a view

I am encountering a JavaScript error while attempting to parse JSON data obtained from my controller: Uncaught SyntaxError: Unexpected token & in JSON at position 1 at JSON.parse () at stores:76 This is the code I use to serialize my list of elem ...

The unusual spinning behavior of child elements in three.js

My current project involves implementing an experimental version of a 2x2x2 Rubik's Cube. I have gathered insights from two previous posts that addressed issues related to attaching and detaching child objects in Three.js: Three.js: Proper way to add ...

change the css back to its original state when a key is pressed

Is there a way to retrieve the original CSS of an element that changes on hover without rewriting it all? Below is my code: $(document).keydown(function(e) { if (e.keyCode == 27) { $(NBSmegamenu).css('display', 'none');} ...

A guide to displaying API response data in a React JS application

As a beginner in react JS, I've encountered a persistent issue. Here is the code: import React from 'react'; class SearchForm extends React.Component { async handleSubmit(event){ event.preventDefault(); try{ const url ='/jobs/ ...

Issue: Unable to locate a change supporting element '[object Object]' of the type 'object - Angular 7'

An angular service has been created for the specified purpose: CheckTicket(barcode, codEspec, diaHoraEspec):Observable<Ticket[]>{ //read ticket return this.http.get<Ticket[]>(`${this.checkticket_url}${barcode}?token=${this.token}&a ...

Encountering problem with selecting values in Select2 with ajax

I have implemented the Select2 plugin in my code as shown below: JavaScript function initAssignmentsAjax() { $("#assignments").empty(); $( "#assignments" ).select2( { placeholder: "Select an assignment", allowCle ...

Achieving consistent text alignment in HTML and CSS without relying on tables

As I delve into the world of HTML and CSS, I've taken a traditional approach by crafting a login page complete with three input controls (two text inputs and one button). To ensure proper alignment of these elements, I initially turned to the trusty & ...

Transferring information to React (Native) hooks in a way similar to how it is done

Transitioning to Hooks in React Native has been a new learning curve for me, especially when it comes to passing data to child elements. In the past with class-based components, passing props was as simple as using XML-style syntax. A Simple Example using ...

The clearTimeout function in React stateless components does not appear to be functioning properly

I am facing an issue with a component that I developed. In this component, one value (inclVal) needs to be larger than another value (exclVal) if both are entered. To ensure that the function handling this comparison doesn't update immediately when pr ...

Develop a stored procedure within phpMyAdmin

Help needed - SQL error: syntax error near '' at line 3 I'm aiming to calculate the total cost of medications This is my SQL query from phpmyadmin: PROCEDURE spMEDICATION_FEE(IN PatientID CHAR(9)) START DECLARE Sum2 INT; DECLARE Sum3 IN ...

Utilizing TypeScript to export a class constructor as a named function

Imagine you have this custom class: export class PerformActionClass<TEntity> { constructor(entity: TEntity) { } } You can use it in your code like this: new PerformActionClass<Person>(myPersonObject); However, you may want a more co ...

Changing the host in every URL within a string using node.js

I am working with a string that contains URLs with IP addresses: { "auth" : { "login" : "http://123.123.11.22:85/auth/signin", "resetpass" : "http://123.123.22.33:85/auth/resetpass", "profile" : "http://123.123.33.44:85/auth/profile" ...

The parameter type 'Object' cannot be assigned to the parameter type 'JSON' in the HttpClient GET method

Hey there! Currently, I'm deep into developing an Angular 6 + Flask application and I've encountered a bit of a snag: Error TS2345: Argument of type 'Object' is not assignable to parameter of type 'JSON'. This issue arises w ...

What is the purpose of having a tsconfig.json file in every subdirectory, even if it just extends the main configuration file?

My goal is to streamline the configuration files in my front-end mono repo by utilizing Vite with React and TypeScript. At the root of my repository, I have set up a tsconfig.json file that contains all the necessary settings to run each project, including ...

The Children Element in Next.js and React Context with TypeScript is lacking certain properties

Encountering a mysterious error while trying to implement React's Context API in Next.js with TypeScript. The issue seems to be revolving around wrapping the context provider around the _app.tsx file. Even though I am passing values to the Context Pr ...

Potential 'undefined' object detected in Vuex mutation using TypeScript

Currently, I am diving into learning Vue.js alongside Vuex and TypeScript. While working on my application, I encountered an error stating "Object is possibly 'undefined'" within the Vuex Store. The error specifically arises in the "newCard" mut ...

Is it possible to extract external JSON data using JQuery's $.getJSON function?

I am trying to retrieve a quote from the iheartquotes website and display it within a div when my webpage loads. However, for some reason, the code I have written is not working as expected. <script type="text/javascript"> $(document).ready( ...

"Utilize Typescript to dynamically check data types during runtime and receive alerts for any potential

INTRODUCTION I am currently working with Angular 6. In Angular, typescript is utilized to allow you to specify the data type of your function's arguments: public fun1(aaa: number) { console.log(aaa); } If I attempt to call fun1 with a parameter ...

What is the process for utilizing GruntFile.coffee and package.json to extract or create the Lungo.js example files?

I want to experiment with the Lungo.js examples found here: https://github.com/tapquo/Lungo.js. However, when I try to run the index.html in the example directory, it seems like the components and package directories are empty. Although these directories d ...

Ways to enable file/result downloads on a website using HTML

Could you please take a look at this repository: https://github.com/imsikka/ArtGallery I am looking to create a downloadable result using a download button. I can create the button, but I am unsure of how to make the file actually downloadable. Do I need ...