Cara Menghasilkan Tipe TypeScript dari Tabel DynamoDB
Di Postgres Anda akan meng-introspeksi information_schema dan menghasilkan
tipe darinya. DynamoDB tidak punya padanannya — dan itu bukan fitur yang
hilang, itu model datanya: DynamoDB sama sekali tidak menyimpan schema
Item. Satu-satunya atribut yang diketahui layanan adalah yang dipakai di
key. AttributeDefinitions milik DescribeTable eksplisit soal cakupannya
sendiri: setiap entri "menjelaskan satu atribut dalam schema key tabel dan
indeks"
(AWS API reference) —
lima puluh atribut lain di tabel Anda memang tidak tercatat di mana pun.
Jadi "menghasilkan tipe TypeScript dari DynamoDB" selalu berarti satu dari tiga hal: mendeklarasikan bentuknya sendiri, menurunkannya dari sebuah schema yang Anda tulis di kode, atau menginferensinya dari Item yang benar-benar ada.
Bagaimana cara mendapatkan tipe TypeScript untuk sebuah tabel DynamoDB?
Tidak ada API yang mengembalikan bentuk Item sebuah tabel — DescribeTable
hanya tahu atribut key. Opsi Anda: menulis-tangan sebuah interface dan
memvalidasi di boundary (sebuah schema Zod menjadikan tipe dan pemeriksaan
runtime satu artefak), memakai library schema-first di mana schema yang Anda
tulis menghasilkan tipenya, atau menginferensi bentuknya dari Item nyata —
lewat skrip, atau dengan alat seperti DynoTable yang men-scan
tabel dan mengekspor sebuah interface TypeScript, schema Zod, atau JSON
Schema.
- Metode 1: tulis-tangan interface-nya (+ Zod di boundary)
- Metode 2: library schema-first (tipe dari schema yang Anda tulis)
- Metode 3: inferensi dari datanya sendiri
Metode 1: tulis-tangan interface + validasi di boundary
AWS SDK tidak bisa mengetik Item Anda untuk Anda. Document client v3
mengembalikan Item sebagai record tanpa tipe — setiap hasil GetCommand /
QueryCommand secara efektif adalah Record<string, unknown> sampai Anda
menegaskan sebaliknya. Sebuah cast as Order telanjang terkompilasi dengan
baik dan berbohong saat runtime, itulah kenapa versi yang tangguh memasangkan
interface dengan pemeriksaan runtime:
import {z} from 'zod';
const Order = z.object({
PK: z.string(), // ORDER#<id>
SK: z.string(), // META
status: z.enum(['open', 'shipped', 'cancelled']),
total: z.number(),
couponCode: z.string().optional() // sparse attribute
});
type Order = z.infer<typeof Order>;
const {Item} = await doc.send(new GetCommand({TableName: 'Orders', Key: key}));
const order = Order.parse(Item); // typed AND verifiedSatu schema, dua pekerjaan: z.infer memberi Anda tipe statis, parse
menangkap Item yang tidak cocok dengannya — yang di sebuah store schemaless
adalah soal kapan, bukan jika. Kelemahannya sama gamblangnya: schema itu
mendokumentasikan niat Anda, bukan tabel Anda. Tidak ada yang mencegah
sebuah writer lama pernah menyimpan total sebagai string, dan tipe
tulisan-tangan melenceng diam-diam seiring data berevolusi.
Jika Anda bekerja dari output API mentah (bukan Document client), ingat bentuk
kabelnya adalah DynamoDB-JSON bertipe-tag ({"S": "..."}, {"N": "123"}) —
lihat marshalling, dan gunakan
konverter DynamoDB JSON untuk membolak-balik
sebuah sampel antara bentuk kabel dan bentuk biasa sembari Anda menulis
schema-nya.
Metode 2: library schema-first
Toolkit seperti ElectroDB dan DynamoDB-Toolbox menyerang masalah drift dari sisi tulis: Anda menulis sebuah schema entity di kode, dan library menurunkan tipe TypeScript-nya dan menegakkan bentuknya pada setiap pembacaan dan penulisan yang ia lakukan. Itu jaminan terkuat yang tersedia — tetapi perhatikan arahnya: Anda yang menulis schema; library tidak menemukannya. Mengarahkannya ke tabel yang sudah ada tetap berarti Anda me-reverse-engineer bentuk Item-nya sendiri lebih dulu, dan Item yang ditulis di luar library berada di luar jaminannya. Mereka bersinar pada single-table design greenfield di mana setiap entity melewati toolkit sejak hari pertama.
Metode 3: inferensi tipe dari Item nyata
Untuk tabel yang sudah ada, kebenaran dasarnya adalah datanya. Scan sebuah sampel, gabungkan bentuk-bentuknya:
const seen = new Map<string, Set<string>>(); // attr -> observed types
let count = 0;
let key: Record<string, unknown> | undefined;
do {
const page = await doc.send(new ScanCommand({TableName: 'Orders', ExclusiveStartKey: key}));
for (const item of page.Items ?? []) {
count++;
for (const [attr, value] of Object.entries(item)) {
const t = Array.isArray(value) ? 'array' : typeof value;
(seen.get(attr) ?? seen.set(attr, new Set()).get(attr)!).add(t);
}
}
key = page.LastEvaluatedKey;
} while (key && count < 5000);
// emit: attribute -> type union, optional if seen in < count itemsJebakan dunia-nyata yang langsung menghantam versi naifnya:
- Atribut sparse. Item DynamoDB dalam satu tabel bisa punya atribut yang
berbeda-beda; sebuah atribut yang hadir di 80% Item adalah
optional, bukan hilang. Lacak frekuensi per-atribut, bukan sekadar kehadirannya. - Entity campuran. Dalam sebuah single-table design,
Item
USER#danORDER#berbagi tabel — satu interface gabungan untuk keduanya tidak berguna. Partisi sampelnya berdasarkan atribut type dan pancarkan satu tipe per entity. - Tabrakan tipe. Atribut yang sama tersimpan sebagai
Ndi sini danSdi sana adalah bug data yang nyata (dan umum) — angkat ia sebagai union alih-alih diam-diam memilih salah satu. Set tag lengkapnya ada di tipe data. - Sampel tetaplah sampel. Atribut yang hanya muncul di Item langka mungkin tidak ada di 5.000 pertama Anda — dan scan itu berbiaya read capacity apa pun hasilnya (query vs scan).
Inferensi satu-klik di DynoTable
Skrip inferensi itu — sampling, pelacakan frekuensi, path bersarang, pemisahan per-entity — sudah terpasang di panel Table stats milik DynoTable:
- Buka sebuah tabel, tekan tombol Stats (ikon bar-chart), dan klik
Index table. DynoTable men-scan tabelnya sekali dengan progres live dan
menemukan setiap atribut yang dibawa Item Anda — termasuk yang bersarang
lewat path bertitik, seperti
commonData.status— beserta tipenya dan apakah ia required atau optional di seluruh baris yang di-scan. - Klik Export dan pilih format:
- TypeScript — sebuah
interface. - Zod — sebuah schema
z.object(...)(kompatibel Standard-Schema). - JSON Schema — draft 2020-12.
- TypeScript — sebuah
- Salin ke clipboard atau simpan ke file.

Ekspornya jujur soal apa dirinya: setiap schema yang dihasilkan dibuka dengan catatan bahwa ia diinferensi dari Item yang di-sampling — titik awal yang kuat, bukan kontrak yang otoritatif. Optionality mencerminkan seberapa sering setiap atribut muncul saat pengindeksan, dan atribut primary-key selalu ditandai required. Pengindeksan menimbulkan biaya baca DynamoDB normal, dan Reindex menyegarkan gambarannya setelah data Anda berubah.
FAQ
Bisakah saya menghasilkan tipe dari DescribeTable?
Hanya untuk atribut key. AttributeDefinitions mencakup schema key tabel dan
indeks — tidak ada hal lain tentang Item Anda yang disimpan layanan, jadi
tidak ada schema sisi-server untuk di-introspeksi.
Apa cara terbaik mengetik tabel produksi yang sudah ada? Inferensi dulu, lalu perkeras: sampling Item nyata (skrip atau ekspor terindeks DynoTable) untuk mendapatkan bentuk sebenarnya, tinjau, dan promosikan menjadi schema Zod milik sendiri atau entity library schema-first agar drift ke depan tertangkap di boundary.
Bagaimana menangani banyak tipe entity dalam satu tabel? Satu tipe per entity, tidak pernah satu tipe gabungan. Pisahkan sampelnya berdasarkan atribut type Anda (atau prefiks key) dan hasilkan interface terpisah untuk masing-masing — discriminated union dari semuanya adalah tipe tabel Anda.
Kenapa tipe hasil generate saya menyebut sebuah field wajib sebagai optional? Karena ada Item ter-sampling yang tidak memilikinya. Di store schemaless, optionality adalah observasi, bukan deklarasi — periksa apakah Item-Item itu baris legacy yang perlu di-backfill (lihat migrasi) atau memang atribut yang benar-benar opsional.
Apakah tipenya mencakup set dan binary DynamoDB? Sebuah konverter harus memilih representasi plain-JSON: set menjadi array dan binary menjadi string ter-encode — keunikan pemetaan yang sama yang dibahas di marshalling. Round-trip sebuah sampel lewat konverter DynamoDB JSON untuk melihat persis seperti apa atribut Anda di tiap sisi.
Berhenti menebak bentuk tabel Anda — unduh DynoTable, indeks tabelnya, dan ekspor TypeScript, Zod, atau JSON Schema dalam satu klik.


