Declaration of 'client' property breaks relations for model
Package version
@adonisjs/[email protected]
node -v
v22.14.0
npm -v
11.4.1
Describe the bug
Relationships typings stopped working after updating project, latest version of packages don't work after fresh install. I see TS2339 and TS2345 errors for most of the relations I use in the codebase. Next are examples:
app/services/project_service.ts:103:40 - error TS2339: Property 'associate' does not exist on type 'never'.
103 await estimate.related('client').associate(client);
~~~~~~~~~
app/services/project_service.ts:104:30 - error TS2345: Argument of type '"generalContractor"' is not assignable to parameter of type 'ExtractModelRelations<Estimate>'.
104 await estimate.related('generalContractor').associate(generalContractor);
~~~~~~~~~~~~~~~~~~~
app/services/project_service.ts:104:51 - error TS2339: Property 'associate' does not exist on type 'never'.
104 await estimate.related('generalContractor').associate(generalContractor);
~~~~~~~~~
It was created a repo with next commands and few file changes without installing or updating anything else.
npm init adonisjs@latest adonisjs-lucid-error-test -- --kit=api --db postgres
cd adonisjs-lucid-error-test/
node ace make:model Task -m
node ace make:model Estimate -m
node ace make:model Project -m
node ace make:model Item -m
node ace make:model Labor -m
node ace make:service ProjectService
I have populated models and service files with the code to address the issue.
Reproduction repo
https://github.com/atassis/adonisjs-lucid-error-test)
Also including console output for initiating an app
npm init adonisjs@latest adonisjs-lucid-error-test -- --kit=api --db postgres
Need to install the following packages:
[email protected]
Ok to proceed? (y) y
> npx
> "create-adonisjs" adonisjs-lucid-error-test --kit=api --db postgres
_ _ _ _ ____
/ \ __| | ___ _ __ (_)___ | / ___|
/ _ \ / _` |/ _ \| '_ \| / __|_ | \___ \
/ ___ \ (_| | (_) | | | | \__ \ |_| |___) |
/_/ \_\__,_|\___/|_| |_|_|___/\___/|____/
❯ Which authentication guard you want to use · session
❯ Download starter kit (1.98 s)
Downloaded "github:adonisjs/api-starter-kit"
❯ Install packages (30 s)
Packages installed using "npm"
❯ Prepare application (915 ms)
Application ready
❯ Configure Lucid (6.77 s)
Lucid configured to use "postgres" database
❯ Configure Auth (8.12 s)
Auth configured to use "session" guard
╭──────────────────────────────────────────────────────────────────╮
│ Your AdonisJS project has been created successfully! │
│──────────────────────────────────────────────────────────────────│
│ │
│ ❯ cd adonisjs-lucid-error-test │
│ ❯ npm run dev │
│ ❯ Open http://localhost:3333 │
│ ❯ │
│ ❯ Have any questions? │
│ ❯ Join our Discord server - https://discord.gg/vDcEjq6 │
│ │
╰──────────────────────────────────────────────────────────────────╯
The issue is with a naming conflict on this line https://github.com/atassis/adonisjs-lucid-error-test/blob/main/app/models/user.ts#L46. There is already BelongsTo.client property, so when a User is used as a relationship, its client points to the overridden property.
Can you try renaming it to something else like userClient and then give it a try?
So I have tested your suggestion and still get an error during build (commit)
> [email protected] build
> node ace build
[ info ] cleaning up output directory (build)
[ info ] compiling typescript source (tsc)
app/services/project_service.ts(47,18): error TS2345: Argument of type '"client"' is not assignable to parameter of type 'ExtractModelRelations<Estimate>'.
app/services/project_service.ts(48,18): error TS2345: Argument of type '"generalContractor"' is not assignable to parameter of type 'ExtractModelRelations<Estimate>'.
app/services/project_service.ts(53,24): error TS2769: No overload matches this call.
Overload 1 of 2, '(callback: (preloader: PreloaderContract<Project>) => void): Promise<void>', gave the following error.
Argument of type 'string' is not assignable to parameter of type '(preloader: PreloaderContract<Project>) => void'.
Overload 2 of 2, '(relation: ExtractModelRelations<Project>, callback?: ((builder: never) => void) | undefined): Promise<void>', gave the following error.
Argument of type '"creator"' is not assignable to parameter of type 'ExtractModelRelations<Project>'.
app/services/project_service.ts(75,29): error TS2345: Argument of type '"client"' is not assignable to parameter of type 'ExtractModelRelations<Project>'.
app/services/project_service.ts(75,39): error TS2339: Property 'associate' does not exist on type 'never'.
app/services/project_service.ts(102,30): error TS2345: Argument of type '"projectProject"' is not assignable to parameter of type 'ExtractModelRelations<Estimate>'.
app/services/project_service.ts(102,48): error TS2339: Property 'associate' does not exist on type 'never'.
app/services/project_service.ts(103,30): error TS2345: Argument of type '"client"' is not assignable to parameter of type 'ExtractModelRelations<Estimate>'.
app/services/project_service.ts(103,40): error TS2339: Property 'associate' does not exist on type 'never'.
app/services/project_service.ts(104,30): error TS2345: Argument of type '"generalContractor"' is not assignable to parameter of type 'ExtractModelRelations<Estimate>'.
app/services/project_service.ts(104,51): error TS2339: Property 'associate' does not exist on type 'never'.
[ info ] rewrited ace file (build/ace.js)
Also I have tested next change- now the project build without exceptions. Still want to admit, that after some change, which I haven't tracked down in my project- I see the same error with any lucid version
I see that you still have client property on some models. Also, this is not related to any specific version of Lucid.
However, in this next release (with breaking changes) we could rename client to use the private namespace $client to workaround the issue.
Do I understand correctly that client is used for something under the hood, which breaks the types for all other relations? And If I change client field to something else- it'll start working correctly for all other relations, too?
I have tested this and it looks so, but want to know this exactly.
Yes, exactly that is the reason.