Skip to content

[finding] driver-sql / driver-turso still publish Promise[any] on five IDataDriver doors after #14438 — findOne, create, bulkCreate, execute, explain on SqlDriver, and TursoDriver.create()'s own override #15267

Description

@zhuangjianguo

Recorded by the os-dev seat executing #14438 (session session_01ARYe3yQTQCUFm5qPYNgKaJ, branch claude/issue-14438-sql-driver-declared-null) as the census that card's triage asked for — "report the count of Promise[any] driver doors in the file, so the next card in this family knows what is left" — filed as its own card so the remainder is not buried in a PR body. Generic type arguments are written in SQUARE brackets because the body sanitizer eats the angle-bracket spelling.

The census, measured on origin/main @ 97bcd99e (2026-09-04)

packages/drivers/driver-sql/src/sql-driver.ts carries 9 raw Promise[any] return annotations. Classified against packages/spec/src/contracts/data-driver.ts (locate by symbol; line numbers drift):

method on IDataDriver? contract declares status
update() yes `Promise[Record[string, unknown] null]`
rotatedUpdateById() (protected, update()'s rotation-path producer) no — internal narrowed with #14438
findOne() yes `Promise[Record[string, unknown] null]`
create() yes Promise[Record[string, unknown]] still Promise[any]
bulkCreate() yes Promise[Record[string, unknown][]] still Promise[any]
execute() yes Promise[unknown] still Promise[any] — the contract's own unknown is erased to any on the class
explain() yes (optional) Promise[unknown] still Promise[any]
analyzeQuery() no — public helper behind explain() Promise[any] (not a door)
aggregate() no — not on the contract (its own comment says so, #6212) Promise[any] (not a door)

So: 6 IDataDriver doors were masked, 1 is un-masked by #14438, 5 remain (findOne, create, bulkCreate, execute, explain), plus 2 non-door helpers.

packages/drivers/driver-turso/src/turso-driver.ts additionally overrides create() with its own explicit Promise[any] (override async create(...)), the same shape its update() override had before #14438 — so driver-turso's published .d.ts re-declares the create door as any on its own and will not inherit a driver-sql fix. Its upsert() override declares Promise[Record[string, any]], which is not the any mask (the null arm is not at stake there) but is not the contract's Record[string, unknown] either; noted, not counted.

SqliteWasmDriver overrides none of these; it inherits every door from SqlDriver. (knex-wasm-dialect.ts has one Promise[any] on a dialect internal — not a driver door.)

Why it matters

Same argument as #14438 / #13878: an explicit any satisfies the widened contract structurally, so tsc says nothing while the published .d.ts tells every consumer holding a SqlDriver / TursoDriver / SqliteWasmDriver that findOne() never returns null and that create() returns whatever they like. Through IDataDriver the same calls are already honest, so the family is honest on the interface and masked on the class — a reader who has learned "the driver doors are narrowed now" is wrong on five of six.

Suggested shape (not a decision)

Per door, the shape #14438 used: replace the annotation with the contract's type, add a type-level pin (IsAny = false, Equals the contract shape) inside each package's own tsc program, and typecheck the consumer closure — a reader that dereferenced the any surfaces as a real error, which is the finding. findOne() is the hottest read in the system and its null arm is the one most likely to surface real missing checks, so it may deserve its own card. Changesets: @objectstack/driver-sql: minor and @objectstack/driver-turso: minor (published .d.ts narrowing, the convention PR #14434 set).

Boundary

driver-memory / driver-mongodb are under the #5499 freeze and are not this card: on the same head, neither carries a Promise[any] door any more (mongodb's update() / upsert() are the contract's since #14428; memory's update() / upsert() since #14434), and driver-memory's remaining find / findOne / create are #14435.

Dedup

search_issues for "driver-sql SqlDriver findOne create bulkCreate execute explain declared return Promise any masked published d.ts" returned #14438 (the update() card, this finding's source) and #14435 (driver-memory's remaining doors) as controls, and no open card for driver-sql's remaining doors.

Related: #14438 · #13878 (ruling A, PR #14434) · #14435 · #14428 · #5499 (freeze boundary).

Filed unassigned for triage.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions