最近、TypeScript
でサーバサイドを書く機会がありました。
DBに MySQL
を利用していましたが、データの挿入や取得の簡単なものでも、少しハマったのでメモを残しておこうと思います。
TypeScript
については、触りたてということで間違いなどがあれば、コメントやTwitterなどで指摘いただければと思います。
作成済みのデータベース
すでに作成しているデータベース、テーブルは以下のような状態になっています。
データベース名:sandbox テーブル名:users
users
id | name |
---|---|
1 | zuckey |
インターフェース
interface User { id?: number; name: string; }
事前準備
ライブラリのimportとMySQLコネクションを作成します。
const { createConnection } = require("mysql"); // ライブラリのimport import { Connection, MysqlError } from "mysql"; // 型定義のimport // コネクションをはる const con: Connection = createConnection({ host: "localhost", port: 13306, user: "root", password: "password", database: "sandbox" });
SELECT
const selectSql = "SELECT * FROM users;"; const getUsers = (): Promise<User[] | Error> => { return new Promise((resolve, reject) => { con.query(selectSql, (err: MysqlError | null, results: any) => { if (err) { reject(err); return; } resolve(results); }); }); } getUsers().then((users: any) => { users.forEach((user: any) => console.log(user.name)); // "zuckey" と表示 process.exit(0); }) .catch((err: Error) => { console.log(err); process.exit(1); });
INSERT
const insertSql = "INSERT INTO users SET ?;"; const createUser = (name: string): Promise<string | Error> => { return new Promise((resolve, reject) => { con.query(insertSql, { name: name }, (err: MysqlError | null, results: any) => { if (err) { reject(err); return; } resolve("success!"); }); }); }; new Promise((resolve, reject) => { con.beginTransaction((err: MysqlError) => { if (err) { reject(err); return; } resolve(getUsers()); }); }) .then((result: any) => { console.log(result); // "success!"と表示 process.exit(0); }) .catch((err: Error) => { console.log(err); process.exit(1); });
ハマった部分
@types/mysql
において、Connection.query
の第2、3引数のqueryCallback
の型定義は以下のようになっています。
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/mysql/index.d.ts#L226
export type queryCallback = (err: MysqlError | null, results?: any, fields?: FieldInfo[]) => void;
そのため、上の例ではこちらにのっとっています。
しかしながら、「typescript mysql」でググると、3番目くらいに出てくる以下のリポジトリを見ると、
https://github.com/types/mysql#usage
queryCallback
の第2引数は、SELECTの場合 RowDataPacket[]
、INSERTの場合 OkPacket
になる、という風に読めます。
スター数などを見ると明らかに怪しいですが、使用例を出してあると、それっぽいな、と思ってしまいました。
まとめ
振り返るとそこまで難しくはないですが、ハマってしまったのは、サードパーティ性ライブラリの TypeScript
の型定義の扱いに慣れていなかったのかなと思いました。
引き続きTypeScript
を触っていき、学習しようと思いますが、MySQL
の利用については、ORM
の利用を考えようと思います。