Type Safety

Get compile-time validation, autocomplete, and runtime checks with genaql's TypeScript integration.

Defining Your Schema

Use defineSchema to declare your database structure:

schema.ts
import { defineSchema } from 'genaql';

export const schema = defineSchema({
  users: {
    id: 'serial',
    name: 'text',
    email: 'text',
    role: { type: 'text', default: 'user' },
    created_at: { type: 'timestamp', default: 'now()' },
    updated_at: 'timestamp?'  // nullable
  },
  posts: {
    id: 'serial',
    title: 'text',
    content: 'text',
    user_id: 'integer',
    published: { type: 'boolean', default: false }
  }
});

Column Types

genaql TypeTypeScriptPostgreSQL
textstringTEXT / VARCHAR
integernumberINTEGER
serialnumberSERIAL
booleanbooleanBOOLEAN
timestampDateTIMESTAMP
jsonunknownJSONB
uuidstringUUID

Compile-Time Validation

TypeScript catches errors before your code runs:

validation.ts
// ✓ Valid - all columns exist
cook`main:users slay:id,name,email`

// ✗ Error - column doesn't exist
cook`main:users slay:id,name,nonexistent`
//                          ^^^^^^^^^^^
// Type Error: Column 'nonexistent' does not exist

// ✗ Error - table doesn't exist
cook`main:invalid_table slay:*`
//        ^^^^^^^^^^^^^
// Type Error: Table 'invalid_table' does not exist

Inferred Return Types

Query results are automatically typed based on your selection:

inferred.ts
const users = await db.query(
  cook`main:users slay:id,name,email sus:active=true`
);

// TypeScript knows the shape:
// users: Array<{ id: number; name: string; email: string }>

users.forEach(user => {
  console.log(user.name);    // ✓ OK
  console.log(user.invalid); // ✗ Error: Property 'invalid' does not exist
});

Runtime Validation

Enable runtime checks for additional safety in development:

runtime.ts
import { createClient } from 'genaql';

const db = createClient({
  dialect: 'postgres',
  pool,
  schema,
  validate: process.env.NODE_ENV === 'development'
});

// In development, invalid queries throw helpful errors
// In production, validation is skipped for performance

Best Practice

Define your schema in a separate file and import it wherever you use genaql. This ensures consistent type checking across your entire codebase.