type User = { name: string email: string }Este es mi código,
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(); } }El código Mysql solo devuelve la matriz
No hay problema con User[] . Pero cuando uso User , quiero eliminar el arreglo.
Así que usé este código, pero no funcionó. ¿Qué tengo que hacer?
Agregué una explicación adicional.
const result = queryWrapper<User>(query, values, conn)
Cuando usa user , sale así.
[ { name: "user-name", email: "user@gmail.com" } ]Pero quiero que salga así.
{ name: "user-name", email: "user@gmail.com" }Contestaré por mi cuenta.
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); }; }cuando llame a 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]; } si <IUser[]>, findByEmail devuelve filas; de lo contrario, devuelve filas.