kysely-org / kysely

A type-safe typescript SQL query builder
https://kysely.dev
MIT License
10.43k stars 266 forks source link

Kysely `insertInto` not triggering compiler error when there are missing required values #1146

Closed dsaltares closed 2 weeks ago

dsaltares commented 2 weeks ago

On kysely@0.27.4.

The following doesn't trigger any errors even though it should because it's missing lots of required properties.

export interface Database {
  exchangeRate: ExchangeRateTable;
}

export interface ExchangeRateTable {
  id: Generated<number>;
  ticker: string;
  open: number;
  low: number;
  high: number;
  close: number;
  date: Timestamp;
  createdAt: Generated<Timestamp>;
  updatedAt: Generated<Timestamp>;
}

export type Timestamp = ColumnType<Date, string | undefined, never>;

const db = new Kysely<Database>({
    dialect: new SqliteDialect({
      database: new SQLite('./db.sqlite'),
    })
});

db.insertInto('exchangeRate')
  .values({
     // This should trigger a TS error
    ticker: 'EURUSD',
  })
  .execute()
  .then(() => {})
  .catch(() => {});

The NullableInsertKeys for this type seems to have all the keys of the type. image

While NotNullableInsertKeys is never. image

The table is created this way:

await db.schema
      .createTable('exchangeRate')
      .addColumn('id', 'integer', (col) => col.primaryKey())
      .addColumn('ticker', 'text', (col) => col.notNull())
      .addColumn('open', 'real', (col) => col.notNull())
      .addColumn('low', 'real', (col) => col.notNull())
      .addColumn('high', 'real', (col) => col.notNull())
      .addColumn('close', 'real', (col) => col.notNull())
      .addColumn('date', 'text', (col) => col.notNull())
      .addColumn('createdAt', 'text', (col) =>
        col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`),
      )
      .addColumn('updatedAt', 'text', (col) =>
        col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`),
      )
      .addUniqueConstraint('unique_exchangeRate_ticker_date', [
        'ticker',
        'date',
      ])
      .execute();

And so the above insert statement yields the following error:

Query failed (Writer) : {
  "durationMs": 0.15899999999999181,
  "sql": "insert into \"exchangeRate\" (\"ticker\") values (?)",
  "params": [
    "EURUSD"
  ],
  "error": {
    "code": "SQLITE_CONSTRAINT_NOTNULL"
  }
}

My tsconfig.json file:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "commonjs",
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "sourceMap": true,
    "baseUrl": ".",
    "outDir": "dist",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "jsx": "react-jsx"
  }
}

Is this a limitation of the sqlite driver? I have another project that uses postgresql that works fine.

Thanks!

dsaltares commented 2 weeks ago

My bad. Was missing 🤦 .

"strict": true

Worth leaving closed as it may useful to others.