Skip to content

Commit a4e44c9

Browse files
authored
fix: nullable relation types (#1130)
1 parent 5499caa commit a4e44c9

File tree

5 files changed

+57
-15
lines changed

5 files changed

+57
-15
lines changed

src/types/model.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,8 @@ export interface LucidRow {
689689
loadAggregate: <
690690
Self extends this,
691691
Name extends ExtractModelRelations<Self>,
692-
RelatedBuilder = Self[Name] extends ModelRelations<LucidModel, LucidModel>
693-
? Self[Name]['subQuery']
692+
RelatedBuilder = NonNullable<Self[Name]> extends ModelRelations<LucidModel, LucidModel>
693+
? NonNullable<Self[Name]>['subQuery']
694694
: never,
695695
>(
696696
name: Name,
@@ -703,8 +703,8 @@ export interface LucidRow {
703703
loadCount: <
704704
Self extends this,
705705
Name extends ExtractModelRelations<Self>,
706-
RelatedBuilder = Self[Name] extends ModelRelations<LucidModel, LucidModel>
707-
? Self[Name]['subQuery']
706+
RelatedBuilder = NonNullable<Self[Name]> extends ModelRelations<LucidModel, LucidModel>
707+
? NonNullable<Self[Name]>['subQuery']
708708
: never,
709709
>(
710710
name: Name,
@@ -758,7 +758,9 @@ export interface LucidRow {
758758
*/
759759
related<Name extends ExtractModelRelations<this>>(
760760
relation: Name
761-
): this[Name] extends ModelRelations<LucidModel, LucidModel> ? this[Name]['client'] : never
761+
): NonNullable<this[Name]> extends ModelRelations<LucidModel, LucidModel>
762+
? NonNullable<this[Name]>['client']
763+
: never
762764
}
763765

764766
/**
@@ -908,8 +910,8 @@ export interface LucidModel {
908910
$getRelation<Model extends LucidModel, Name extends ExtractModelRelations<InstanceType<Model>>>(
909911
this: Model,
910912
name: Name
911-
): InstanceType<Model>[Name] extends ModelRelations<LucidModel, LucidModel>
912-
? InstanceType<Model>[Name]['client']['relation']
913+
): NonNullable<InstanceType<Model>[Name]> extends ModelRelations<LucidModel, LucidModel>
914+
? NonNullable<InstanceType<Model>[Name]>['client']['relation']
913915
: RelationshipsContract
914916
$getRelation<Model extends LucidModel>(this: Model, name: string): RelationshipsContract
915917

src/types/relations.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -992,8 +992,8 @@ export interface ManyToManySubQueryBuilderContract<Related extends LucidModel>
992992
export interface WithCount<Model extends LucidRow, Builder> {
993993
<
994994
Name extends ExtractModelRelations<Model>,
995-
RelatedBuilder = Model[Name] extends ModelRelations<LucidModel, LucidModel>
996-
? Model[Name]['subQuery']
995+
RelatedBuilder = NonNullable<Model[Name]> extends ModelRelations<LucidModel, LucidModel>
996+
? NonNullable<Model[Name]>['subQuery']
997997
: never,
998998
>(
999999
relation: Name,
@@ -1007,8 +1007,8 @@ export interface WithCount<Model extends LucidRow, Builder> {
10071007
export interface WithAggregate<Model extends LucidRow, Builder> {
10081008
<
10091009
Name extends ExtractModelRelations<Model>,
1010-
RelatedBuilder = Model[Name] extends ModelRelations<LucidModel, LucidModel>
1011-
? Model[Name]['subQuery']
1010+
RelatedBuilder = NonNullable<Model[Name]> extends ModelRelations<LucidModel, LucidModel>
1011+
? NonNullable<Model[Name]>['subQuery']
10121012
: never,
10131013
>(
10141014
relation: Name,
@@ -1033,8 +1033,8 @@ export interface Has<Model extends LucidRow, Builder> {
10331033
export interface WhereHas<Model extends LucidRow, Builder> {
10341034
<
10351035
Name extends ExtractModelRelations<Model>,
1036-
RelatedBuilder = Model[Name] extends ModelRelations<LucidModel, LucidModel>
1037-
? Model[Name]['subQuery']
1036+
RelatedBuilder = NonNullable<Model[Name]> extends ModelRelations<LucidModel, LucidModel>
1037+
? NonNullable<Model[Name]>['subQuery']
10381038
: never,
10391039
>(
10401040
relation: Name,
@@ -1056,8 +1056,8 @@ export interface WhereHas<Model extends LucidRow, Builder> {
10561056
export interface Preload<Model extends LucidRow, Builder> {
10571057
<
10581058
Name extends ExtractModelRelations<Model>,
1059-
RelatedBuilder = Model[Name] extends ModelRelations<LucidModel, LucidModel>
1060-
? Model[Name]['builder']
1059+
RelatedBuilder = NonNullable<Model[Name]> extends ModelRelations<LucidModel, LucidModel>
1060+
? NonNullable<Model[Name]>['builder']
10611061
: never,
10621062
>(
10631063
relation: Name,

src/types/test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* @adonisjs/lucid
3+
*
4+
* (c) Harminder Virk <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
export type ExtractRelationCallback<
11+
T extends (...args: any[]) => any,
12+
Callback = NonNullable<Parameters<T>[1]>,
13+
> = Callback extends (...args: any[]) => any ? Parameters<Callback>[0] : never

test/orm/model_belongs_to.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
getDb,
2323
} from '../../test-helpers/index.js'
2424
import { AppFactory } from '@adonisjs/core/factories/app'
25+
import { ExtractRelationCallback } from '../../src/types/test.js'
2526

2627
test.group('Model | BelongsTo | Options', (group) => {
2728
group.setup(async () => {
@@ -238,11 +239,25 @@ test.group('Model | BelongsTo | Options', (group) => {
238239
}
239240

240241
class Profile extends BaseModel {
242+
@column()
243+
declare userId: number
244+
241245
@belongsTo(() => User)
242246
declare user?: BelongsTo<typeof User> | null
243247
}
244248

249+
const preload = Profile.query().preload<'user'>
250+
const withCount = Profile.query().withCount<'user'>
251+
const withAggregate = Profile.query().withAggregate<'user'>
252+
const whereHas = Profile.query().whereHas<'user'>
253+
const related = new Profile().related('user')
254+
245255
expectTypeOf<ExtractModelRelations<Profile>>().toEqualTypeOf<'user' | undefined>()
256+
expectTypeOf<ExtractRelationCallback<typeof preload>>().not.toBeNever()
257+
expectTypeOf<ExtractRelationCallback<typeof withCount>>().not.toBeNever()
258+
expectTypeOf<ExtractRelationCallback<typeof withAggregate>>().not.toBeNever()
259+
expectTypeOf<ExtractRelationCallback<typeof whereHas>>().not.toBeNever()
260+
expectTypeOf<typeof related>().not.toBeNever()
246261
})
247262
})
248263

test/orm/model_has_one.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
resetTables,
2424
} from '../../test-helpers/index.js'
2525
import { AppFactory } from '@adonisjs/core/factories/app'
26+
import { ExtractRelationCallback } from '../../src/types/test.js'
2627

2728
test.group('Model | HasOne | Options', (group) => {
2829
group.setup(async () => {
@@ -252,7 +253,18 @@ test.group('Model | HasOne | Options', (group) => {
252253
declare profile?: HasOne<typeof Profile> | null
253254
}
254255

256+
const preload = User.query().preload<'profile'>
257+
const withCount = User.query().withCount<'profile'>
258+
const withAggregate = User.query().withAggregate<'profile'>
259+
const whereHas = User.query().whereHas<'profile'>
260+
const related = new User().related('profile')
261+
255262
expectTypeOf<ExtractModelRelations<User>>().toEqualTypeOf<'profile' | undefined>()
263+
expectTypeOf<ExtractRelationCallback<typeof preload>>().not.toBeNever()
264+
expectTypeOf<ExtractRelationCallback<typeof withCount>>().not.toBeNever()
265+
expectTypeOf<ExtractRelationCallback<typeof withAggregate>>().not.toBeNever()
266+
expectTypeOf<ExtractRelationCallback<typeof whereHas>>().not.toBeNever()
267+
expectTypeOf<typeof related>().not.toBeNever()
256268
})
257269
})
258270

0 commit comments

Comments
 (0)