最近、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の利用を考えようと思います。