こんにちは、フリーランスエンジニアの太田雅昭です。
今回はDexieでのdeleteメソッドにおける型についてです。
Dexie
Dexieは、IndexedDBを簡単に使えるライブラリです。
今回下記のバージョンを使用しています
"dexie": "^4.3.0"
単一キーでの使用
単一キーでは、特に問題なく型をつけることができます。下記のようにします。型エラーもなく、意図通りに動作します。
type Item = {
id: string;
};
const db = new Dexie("Items") as Dexie & {
items: EntityTable<Item, "id">;
};
db.version(1).stores({
items: "id",
});
// 更新
await db.items.put({ id: "abc" });
// データがある
console.log(await db.items.get("abc"));
// 削除
await db.items.delete("abc");
// データがない
console.log(await db.items.get("abc"));
複合キーでのdelete
一方複合キーでは、getは以下のように書けます。特に問題はありません。
await db.items.get(["abc", "def"])
同じくdeleteも書いてみます。
await db.items.delete(["abc", "def"]);
しかしこのdeleteは型エラーが出ます。
Argument of type 'string[]' is not assignable to parameter of type 'string'.
これはEntityTableが複合キーに対応しきれていないことが原因のようです。issueも立てられています。
https://github.com/dexie/Dexie.js/issues/1990
このissueは2024年のもので、今と挙動が違うようですが、いまだにopenであることから複合キーに対応していない事は変わり無いようです。
anyで逃げる
この問題は、deleteにanyを使用する事で回避できます。根本的な解決ではありませんが、一旦これで逃げるのが良さそうです。
await db.items.delete(["abc", "def"] as any);
全体のコードは以下のようになります。
type CompositeItem = {
id1: string;
id2: string;
};
const db = new Dexie("CompositeItems") as Dexie & {
items: EntityTable<CompositeItem, "id1" | "id2">;
};
db.version(1).stores({
items: "[id1+id2]",
});
// 更新
await db.items.put({ id1: "abc", id2: "def" });
// データがある
console.log(await db.items.get(["abc", "def"]));
// 削除
await db.items.delete(["abc", "def"] as any);
// データがない
console.log(await db.items.get(["abc", "def"]));
まとめ
Dexieは便利ですが、型が若干弱い点が気になります。もっともPrismaやDrizzleが強すぎるのかも知れません。型が複雑になるにつれ、人間が読むのが困難になってきますので、今後はこういう部分でAIが役立ってきそうですね。