Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

297
Views
If the mysql result value is an array and generic T is not an array, can it be removed in typescript?
type User = {
  name: string
  email: string
}

This is my code,

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();
  }
}

Mysql code only returns the array

There is no problem with User[]. But When using User, I want to remove the arrangement.

So I used this code, but it didn't work. What should I do?



I added additional explanation.

const result = queryWrapper<User>(query, values, conn)
When use user, It comes out like this.

[
  {
   name: "user-name",
   email: "user@gmail.com"
  }
]

But I want it comes out like this.

{
 name: "user-name",
 email: "user@gmail.com"
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I'll reply by myself.

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 call 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 returns rows else returns rows

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!