Skip to content

Bug: payload generate:db-schema produces TypeScript errors (TS7022/TS7024) on circular table references #15733

@magicspon

Description

@magicspon

Describe the Bug

Running payload generate:db-schema generates a payload-generated-schema.ts file that contains circular foreign key references between tables (e.g. media → teams → organizations → media). TypeScript cannot infer the types for these tables and raises implicit any errors, even though AnyPgColumn is already imported in the generated file.

Steps to Reproduce

  1. Create a Payload project with @payloadcms/db-postgres
  2. Define collections with cross-referencing relationships, e.g.:
    • media has a team relationship field → teams
    • organizations has an image relationship field → media
    • teams has an organization relationship field → organizations
  3. Run payload generate:db-schema
  4. Run tsc --noEmit

Errors

src/payload-generated-schema.ts(2195,14): error TS7022: 'media' implicitly has type 'any' because it does not
  have a type annotation and is referenced directly or indirectly in its own initializer.
src/payload-generated-schema.ts(2205,36): error TS7024: Function implicitly has return type 'any' because it
  does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
src/payload-generated-schema.ts(3562,14): error TS7022: 'organizations' implicitly has type 'any' because it
  does not have a type annotation and is referenced directly or indirectly in its own initializer.
src/payload-generated-schema.ts(3569,38): error TS7024: Function implicitly has return type 'any' because it
  does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
src/payload-generated-schema.ts(3596,14): error TS7022: 'teams' implicitly has type 'any' because it does not
  have a type annotation and is referenced directly or indirectly in its own initializer.
src/payload-generated-schema.ts(3601,52): error TS7024: Function implicitly has return type 'any' because it
  does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.

Root Cause

The generated code uses deferred .references(() => otherTable.id) callbacks to handle forward references, but TypeScript still cannot resolve the types when tables form a cycle. The AnyPgColumn type is imported but not applied to the circular reference columns.

The offending pattern:

export const media = pgTable('media', {
  team: uuid('team_id').references(() => teams.id, { onDelete: 'set null' }),
  //                                  ^^^^ 'teams' not yet typed → implicit any
})

export const organizations = pgTable('organizations', {
  image: uuid('image_id').references(() => media.id, { onDelete: 'set null' }),
})

export const teams = pgTable('teams', {
  organization: uuid('organization_id').references(() => organizations.id, { onDelete: 'set null' }),
})

Expected Behaviour

The generated file should either:

  1. Annotate circular reference callbacks with AnyPgColumn (the import is already present):
    team: uuid('team_id').references((): AnyPgColumn => teams.id, { onDelete: 'set null' }),
  2. Or prepend // @ts-nocheck to the generated file, consistent with the existing /* tslint:disable */ / /* eslint-disable */ directives already present.

Workaround

Prepend // @ts-nocheck after each generation via a wrapper script in package.json:

"generate:db-schema": "payload generate:db-schema && node --input-type=module -e \"import{readFileSync,writeFileSync}from'fs';const f='src/payload-generated-schema.ts';writeFileSync(f,'// @ts-nocheck\\n'+readFileSync(f,'utf8'))\""

Which area(s) are affected?

db: postgres

Environment Info

payload: ^3.77.0
@payloadcms/db-postgres: ^3.77.0
typescript: ^5.9.3
Node: 22

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions