I am working on an application using NextJS and Typescript and am attempting to determine the best way to properly type my MySQL responses. Here is the API endpoint:
import { hash } from "bcrypt";
import type { NextApiRequest, NextApiResponse } from "next";
import randomstring from "randomstring";
import { executeQuery } from "../../../lib/db";
const Test = async (req: NextApiRequest, res: NextApiResponse) => {
// Manage password generation
const password = randomstring.generate(16);
const hashedPassword = hash(password, 10);
// Create new auth using email and password
const auth = await executeQuery(
"INSERT INTO auth (email, password) VALUES (?, ?)",
["[email protected]", (await hashedPassword).toString()]
);
res.statusCode = 200;
res.json(auth.insertId);
};
export default Test;
I am wanting to strongly type insertId
to remove all warnings and errors through ESLint, but unfortunately, every effort I have made has been unsuccessful. The error I am getting is:
Property 'insertId' does not exist on type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader | { error: unknown; }'.
Property 'insertId' does not exist on type 'RowDataPacket[]'.ts(2339)
My executeQuery
function is defined as:
import mysql from "mysql2/promise";
export const executeQuery = async (query: string, params: unknown[] = []) => {
try {
const db = await mysql.createConnection({
host: process.env.MYSQL_HOST,
database: process.env.MYSQL_DATABASE,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
});
const [results] = await db.execute(query, params);
db.end();
return results;
} catch (error) {
return { error };
}
};
One of my implementation attempts was this SO response but I could not get it to work…
Any and all help is greatly appreciated!
2
Answers
So, I managed to solve my own problem after tackling it for a while.
It turns out, I was doing my checks incorrectly.
Before calling
auth.insertId
, you'll want to include the following check:That way, you don't actually have to type anything, because it can get super complicated when you are attempting to do that with mysql.
I did as well get myself in the same problem as you, after looking up in the mysql2 types files, I found you can pass the result type of the query.
For example:
For inserts and updates you can be using the
OkPacket
type and for selects you can useRowDataPacket
. You can type it even further by implementingRowDataPacket
to the expected responsey type of the query and passing it in the query function.For example:
Then when you are querying you can pass as follows:
Here it is my 2 cents, hope it helps someone in the future.