TypeScriptでMySQLを触るメモ

最近、TypeScript でサーバサイドを書く機会がありました。
DBに MySQLを利用していましたが、データの挿入や取得の簡単なものでも、少しハマったのでメモを残しておこうと思います。
TypeScriptについては、触りたてということで間違いなどがあれば、コメントやTwitterなどで指摘いただければと思います。

github.com

作成済みのデータベース

すでに作成しているデータベース、テーブルは以下のような状態になっています。

データベース名: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番目くらいに出てくる以下のリポジトリを見ると、

f:id:zuckey_17:20180317073552p:plain:w300

https://github.com/types/mysql#usage

queryCallbackの第2引数は、SELECTの場合 RowDataPacket[]、INSERTの場合 OkPacketになる、という風に読めます。
スター数などを見ると明らかに怪しいですが、使用例を出してあると、それっぽいな、と思ってしまいました。

まとめ

振り返るとそこまで難しくはないですが、ハマってしまったのは、サードパーティ性ライブラリの TypeScriptの型定義の扱いに慣れていなかったのかなと思いました。
引き続きTypeScriptを触っていき、学習しようと思いますが、MySQLの利用については、ORMの利用を考えようと思います。