Skip to content

TypeScript: insert()/update()/upsert() argument type too permissive #1636

@borispetrovdev

Description

@borispetrovdev

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

When using the Supabase JavaScript client (supabase-js), mutation methods such as .update() allow passing object keys that don’t correspond to actual table columns. These invalid keys don’t trigger a TypeScript error, only a runtime error from the database.

This means TypeScript does not enforce strict column checks on Database["public"]["Tables"]["<table>"]["update"] types.

To Reproduce

  1. Create a table todos with the following columns:
id uuid primary key,
description text,
completed boolean
  1. Generate the TypeScript types. The Database["public"]["Tables"]["todos"]["update"] type will look like:
{
  id?: string;
  description?: string;
  completed?: boolean;
}
  1. Call the update function with an extra key that isn’t part of the table:
await supabase
.from("todos")
.update({
  completed: true,
  some_random_key: "foo", // ❌ not a real column
})
.eq("id", "someTodoId");
  1. Observe that:
  • At compile time: no TypeScript error
  • At runtime: a database error is thrown

Expected behavior

I expected both:

  • A runtime error from Postgres (which happens)
  • A compile-time error from TypeScript (which does not happen)

This way, dropping or renaming a column would result in a TS error when the code references it. Currently, errors slip through to production if not caught in runtime testing.

System information

  • Version of supabase-js: 2.52.0

Additional context

I acknowledge that TS has a well-known “excess property checks” quirk (though I don't think this issue is an example of that). Here's what I mean:

function someFunc(params: { foo: string }) {}
someFunc({ foo: "foo", bar: "bar" }) // ✅ error expected, and indeed TS errors
const someParams = { foo: "foo", bar: "bar"};
someFunc(someParams); // NO error expected!

But with Supabase’s update() type, inlined excess keys do not error. I’m curious if this is a conscious design decision, a TypeScript technical constraint, or an actual bug in the type generation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpostgrest-jsRelated to the postgrest-js library.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions