Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

306
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda