
2026/02/18 3:15
「PG‑typesafe – PostgreSQLとTypeScript用の厳格に型付けされたクエリ」
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
## pg‑typesafe – TypeScript 用に完全型安全な PostgreSQL `pg-typesafe` は接続文字列から自動的に `src/defs.gen.ts` ファイルを生成し、実行時の依存関係や余分なボイラープレートを追加せずにコンパイル時にすべてのクエリの型安全性を提供します。 ### 使い始め ```bash npm exec pg-typesafe -- \ --connectionString postgres://postgres:example@localhost \ --definitionsFile src/defs.gen.ts
CLI は以下のオプションを受け付けます(デフォルトは下記の通り)。
– データベース URL--connectionString
– 出力ファイル (--definitionsFile
がデフォルト)src/defs.gen.ts
– TypeScript 設定ファイル (--tsConfigFile
がデフォルト)tsconfig.json
– 任意の--configFilepg-typesafe.config.ts
例:
pg-typesafe.config.ts
import { defineConfig } from 'pg-typesafe'; export default defineConfig({ connectionString: process.env.DATABASE_URL!, });
生成された型を使用する
生成された型に
Pool をキャストします。
import { TypesafePool } from './defs.gen'; const pool = new Pool() as TypesafePool; await pool.query('SELECT * FROM users WHERE id=$1', [42]); // パラメータと行が型付き
キャスト後に再度生成器 (
pg-typesafe …) を実行して、追加された型情報を含む定義を再生成します。
特殊な PostgreSQL 型の取り扱い
-
BIGINT → BigInt
import { pg } from 'pg'; pg.types.setTypeParser(20, val => BigInt(val)); // または defs.gen.ts の transformParameter/transformField を通じて -
JSONB カラム –
を生成された型名(例:type_oid === 3802
)にマップし、自動的に作成されるhello_data
からインポートします。jsonb_columns.ts
接続をヘルパー関数へ渡す際は、拡張クライアント/クエリャー型 (
TypesafePoolClient, TypesafeQuerier) を使用して型情報が正しく伝播するようにしてください。
制限事項
定数 SQL 文字列のみ解析可能です。動的クエリは型チェックできません。
代替案
- pgtyped – 別途
と.ts
ファイルを必要とし、より冗長です。.sql - kysely – 独自の型システムを持つクエリビルダーライブラリです。
## Text to translate (incorporating all missing elements while keeping clarity):**
本文
pg-typesafe
pg‑typesafe は、実行時に依存関係を持たず、冗長性もゼロで PostgreSQL のクエリに対して TypeScript 型を生成します。
例:クエリ
const { rows } = client.query( "select id, name, last_modified from tbl where id = $1", [42], );
このクエリは通常の
pg クエリと同じ構文ですが、完全に型付けされています:
- パラメータは必須であり、数値でなければならない。
はrows
型になる。{ id: number; name: string; last_modified: Date }[]
使い始め
-
インストール
npm i pg-typesafe -
型を生成(初回)
npm exec pg-typesafe -- \ --connectionString postgres://postgres:example@localhostこれにより
が作成され、そこに生成された型が格納されます。src/defs.gen.ts -
型を使用
import type { TypesafePool } from "./defs.gen.ts"; export const pool = new Pool() as TypesafePool; -
必要時に再生成
npm exec pg-typesafe -- \ --connectionString postgres://postgres:example@localhost
制限事項
- SQL 文字列が定数であるクエリのみが型付け可能です。動的なクエリは解析できません。
- SQL インジェクションを防止し、パフォーマンス向上のために定数を使用してください。
コマンドラインオプション
| オプション | デフォルト | 説明 |
|---|---|---|
| undefined | PostgreSQL の接続文字列。PGHOST、PGDATABASE などもサポート。 |
| | 型定義ファイルへのパス。 |
| | 分析対象のファイルを検索する tsconfig。 |
| | 設定ファイル。 |
設定ファイル
基本的な
:pg-typesafe.config.ts
import { defineConfig } from "pg-typesafe"; export default defineConfig({ connectionString: "postgres://postgres:example@localhost", });
パラメータの完全リストは JSDoc を通じて文書化されています。
レシピ
BIGINT を JavaScript の bigint
に変換
bigint-
pg 側(Node.js の新しいバージョンでは
がサポートされます):bigintimport { types } from "pg"; types.setTypeParser(20, val => BigInt(val)); -
pg-typesafe 設定:
export default defineConfig({ // パラメータが BIGINT の場合 transformParameter(param) { if (param.type_oid === 20) return { type: "bigint" }; return defaultTransformParameter(param); }, // 結果フィールドが BIGINT の場合 transformField(field) { if (field.type_oid === 20) return { type: "bigint" }; return defaultTransformField(field); }, });
JSONB カラムをコンテキストに応じて型付け
-
設定:
export default defineConfig({ transformField(field) { if (field.type_oid === 3802 && field.column) { const c = field.column; const typeName = `${c.table_name}_${c.column_name}`; return { type: typeName, imports: [{ name: typeName, path: "./jsonb_columns.ts" }], }; } return defaultTransformField(field); }, }); -
型を定義(例:テーブル
に JSONB カラムhello
がある場合):dataexport interface hello_data { foo: string; bar: number; }
型の継承
拡張された型は自動的に使用され、
pool.connect で取得したクライアントでも機能します。関数へ接続を渡す際には特定の型を使います:
async function fetchFoos(client: TypesafeQuerier) { const { rows } = await client.query("select id, name from foo"); return rows; }
他ツールとの比較
| ツール | 備考 |
|---|---|
| pgtyped | と に対して型を生成します。 の場合、冗長で独自のヘルパーが使用されます。 は への追加の冗長性はありません。 |
| kysely | SQL 構文に近いタイプセーフなクエリビルダーです。 |