【Drizzle ORM】Value Objectに変換するCustom typeを定義する

Drizzle ORMでDBからの値 ←→ Value Objectのインスタンスの相互変換をしたい時、Custom typesを実装することで実現できそう。

ちなみにValue Objectは下記のように実装した前提で進める。

【TypeScript】Value Object(値オブジェクト)を実装する

解決法

import { customType } from 'drizzle-orm/pg-core';
function valueObjectType<T extends new (v: any) => ValueObject<typeof v>>(
baseClass: T,
dataType: string,
columnName: string,
) {
const type = customType<{
data: InstanceType<T>;
driverData: InstanceType<T>['value'];
}>({
dataType() {
return dataType;
},
toDriver({ value }) {
return value;
},
fromDriver(value) {
return new baseClass(value) as InstanceType<T>;
},
});
return type(columnName);
}

カスタム型の実装ために提供されているジェネレータ関数customType()を利用する1

  1. 対象のクラス
  2. データ型
  3. カラム名

を引数で受け取り、ドライバーに渡す時はvalueを、ドライバーから受け取った時はValue Objectとしてインスタンス化するようにする。

const products = pgTable(
'products',
{
...
price: valueObjectType(Price, 'smallint', 'price'),
},
);

利用方法としてはスキーマ定義時に上記のように呼び出すだけ。

参考
  1. DBの種類によってimport元は変わってくる