如果 mysql 结果值是数组而泛型 T 不是数组,是否可以在打字稿中将其删除?
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
}
这是我的代码,
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 仅代码 returns 数组
User[]
没有问题。
但是当使用User
时,我想删除排列。
所以我用了这个代码,但是没有用。我该怎么办?
我添加了额外的解释。
const result = queryWrapper<User>(query, values, conn)
使用user
时,结果是这样的
[
{
name: "user-name",
email: "user@gmail.com"
}
]
但我希望它是这样的。
{
name: "user-name",
email: "user@gmail.com"
}
我自己回复。
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);
};
}
调用 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 , findByEmail
returns 行
否则 returns 行
type User = {
name: string
email: string
}
这是我的代码,
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 仅代码 returns 数组
User[]
没有问题。
但是当使用User
时,我想删除排列。
所以我用了这个代码,但是没有用。我该怎么办?
我添加了额外的解释。
const result = queryWrapper<User>(query, values, conn)
使用user
时,结果是这样的
[
{
name: "user-name",
email: "user@gmail.com"
}
]
但我希望它是这样的。
{
name: "user-name",
email: "user@gmail.com"
}
我自己回复。
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);
};
}
调用 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 findByEmail
returns 行
否则 returns 行