Skip to content

Commit 63ed0be

Browse files
committed
feat: updated static methods returning models to infer type from this
1 parent 53c6d7a commit 63ed0be

File tree

4 files changed

+70
-38
lines changed

4 files changed

+70
-38
lines changed

docs/cookbook.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,9 @@ export default class Model extends BaseModel implements FormatsQueryParameters {
185185
this.appends.push(name);
186186
return this;
187187
}
188-
189-
public static append<T extends Model>(name: string): T {
188+
189+
// @ts-expect-error - despite TS2526, it still infers correctly
190+
public static append<T extends Model = InstanceType<this>>(name: string): T {
190191
this.newQuery<T>().append(name);
191192
}
192193

src/Calliope/Concerns/BuildsQuery.ts

+52-26
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ export default class BuildsQuery extends HasAttributes {
152152
*
153153
* @return {BuildsQuery}
154154
*/
155-
public static newQuery<T extends Model>(): T {
155+
// @ts-expect-error - despite TS2526, it still infers correctly
156+
public static newQuery<T extends Model = InstanceType<this>>(): T {
156157
return new this as T;
157158
}
158159

@@ -330,7 +331,8 @@ export default class BuildsQuery extends HasAttributes {
330331
*
331332
* @see BuildsQuery.prototype.where
332333
*/
333-
public static where<T extends Model>(
334+
// @ts-expect-error - despite TS2526, it still infers correctly
335+
public static where<T extends Model = InstanceType<this>>(
334336
column: string,
335337
operator: Operator | unknown,
336338
value?: unknown,
@@ -383,7 +385,8 @@ export default class BuildsQuery extends HasAttributes {
383385
*
384386
* @see BuildsQuery.prototype.whereKey
385387
*/
386-
public static whereKey<T extends Model>(
388+
// @ts-expect-error - despite TS2526, it still infers correctly
389+
public static whereKey<T extends Model = InstanceType<this>>(
387390
value: MaybeArray<number | string>, boolean: BooleanOperator = 'and'
388391
): T {
389392
return this.newQuery<T>().whereKey(value, boolean);
@@ -426,7 +429,8 @@ export default class BuildsQuery extends HasAttributes {
426429
*
427430
* @see BuildsQuery.prototype.whereNotIn
428431
*/
429-
public static whereKeyNot<T extends Model>(
432+
// @ts-expect-error - despite TS2526, it still infers correctly
433+
public static whereKeyNot<T extends Model = InstanceType<this>>(
430434
value: MaybeArray<number | string>, boolean: BooleanOperator = 'and'
431435
): T {
432436
return this.newQuery<T>().whereKeyNot(value, boolean);
@@ -470,7 +474,8 @@ export default class BuildsQuery extends HasAttributes {
470474
*
471475
* @see BuildsQuery.prototype.whereNull
472476
*/
473-
public static whereNull<T extends Model>(columns: MaybeArray<string>): T {
477+
// @ts-expect-error - despite TS2526, it still infers correctly
478+
public static whereNull<T extends Model = InstanceType<this>>(columns: MaybeArray<string>): T {
474479
return this.newQuery<T>().whereNull(columns);
475480
}
476481

@@ -512,7 +517,8 @@ export default class BuildsQuery extends HasAttributes {
512517
*
513518
* @see BuildsQuery.prototype.whereNotNull
514519
*/
515-
public static whereNotNull<T extends Model>(columns: MaybeArray<string>): T {
520+
// @ts-expect-error - despite TS2526, it still infers correctly
521+
public static whereNotNull<T extends Model = InstanceType<this>>(columns: MaybeArray<string>): T {
516522
return this.newQuery<T>().whereNotNull(columns);
517523
}
518524

@@ -549,7 +555,8 @@ export default class BuildsQuery extends HasAttributes {
549555
*
550556
* @see BuildsQuery.prototype.whereIn
551557
*/
552-
public static whereIn<T extends Model>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
558+
// @ts-expect-error - despite TS2526, it still infers correctly
559+
public static whereIn<T extends Model = InstanceType<this>>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
553560
return this.newQuery<T>().whereIn(column, values, boolean);
554561
}
555562

@@ -587,7 +594,8 @@ export default class BuildsQuery extends HasAttributes {
587594
*
588595
* @see BuildsQuery.prototype.whereNotIn
589596
*/
590-
public static whereNotIn<T extends Model>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
597+
// @ts-expect-error - despite TS2526, it still infers correctly
598+
public static whereNotIn<T extends Model = InstanceType<this>>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
591599
return this.newQuery<T>().whereNotIn(column, values, boolean);
592600
}
593601

@@ -630,7 +638,8 @@ export default class BuildsQuery extends HasAttributes {
630638
*
631639
* @see BuildsQuery.prototype.whereBetween
632640
*/
633-
public static whereBetween<T extends Model>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
641+
// @ts-expect-error - despite TS2526, it still infers correctly
642+
public static whereBetween<T extends Model = InstanceType<this>>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
634643
return this.newQuery<T>().whereBetween(column, values, boolean);
635644
}
636645

@@ -673,7 +682,8 @@ export default class BuildsQuery extends HasAttributes {
673682
*
674683
* @see BuildsQuery.prototype.whereNotBetween
675684
*/
676-
public static whereNotBetween<T extends Model>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
685+
// @ts-expect-error - despite TS2526, it still infers correctly
686+
public static whereNotBetween<T extends Model = InstanceType<this>>(column: string, values: any[], boolean: BooleanOperator = 'and'): T {
677687
return this.newQuery<T>().whereNotBetween(column, values, boolean);
678688
}
679689

@@ -715,7 +725,8 @@ export default class BuildsQuery extends HasAttributes {
715725
*
716726
* @see BuildsQuery.prototype.limit
717727
*/
718-
public static limit<T extends Model>(count: number): T {
728+
// @ts-expect-error - despite TS2526, it still infers correctly
729+
public static limit<T extends Model = InstanceType<this>>(count: number): T {
719730
return this.newQuery<T>().limit(count);
720731
}
721732

@@ -740,7 +751,8 @@ export default class BuildsQuery extends HasAttributes {
740751
*
741752
* @see BuildsQuery.prototype.page
742753
*/
743-
public static page<T extends Model>(pageNumber: number): T {
754+
// @ts-expect-error - despite TS2526, it still infers correctly
755+
public static page<T extends Model = InstanceType<this>>(pageNumber: number): T {
744756
return this.newQuery<T>().page(pageNumber);
745757
}
746758

@@ -770,7 +782,8 @@ export default class BuildsQuery extends HasAttributes {
770782
*
771783
* @see BuildsQuery.prototype.when
772784
*/
773-
public static when<T extends Model>(value: any, closure: (instance: BuildsQuery) => any): T {
785+
// @ts-expect-error - despite TS2526, it still infers correctly
786+
public static when<T extends Model = InstanceType<this>>(value: any, closure: (instance: BuildsQuery) => any): T {
774787
return this.newQuery<T>().when(value, closure);
775788
}
776789

@@ -800,7 +813,8 @@ export default class BuildsQuery extends HasAttributes {
800813
*
801814
* @see BuildsQuery.prototype.unless
802815
*/
803-
public static unless<T extends Model>(value: any, closure: (instance: BuildsQuery) => any): T {
816+
// @ts-expect-error - despite TS2526, it still infers correctly
817+
public static unless<T extends Model = InstanceType<this>>(value: any, closure: (instance: BuildsQuery) => any): T {
804818
return this.newQuery<T>().unless(value, closure);
805819
}
806820

@@ -822,7 +836,8 @@ export default class BuildsQuery extends HasAttributes {
822836
*
823837
* @see BuildsQuery.prototype.distinct
824838
*/
825-
public static distinct<T extends Model>(columns: MaybeArray<string>): T {
839+
// @ts-expect-error - despite TS2526, it still infers correctly
840+
public static distinct<T extends Model = InstanceType<this>>(columns: MaybeArray<string>): T {
826841
return this.newQuery<T>().distinct(columns);
827842
}
828843

@@ -848,7 +863,8 @@ export default class BuildsQuery extends HasAttributes {
848863
*
849864
* @see BuildsQuery.prototype.select
850865
*/
851-
public static select<T extends Model>(columns: MaybeArray<string>): T {
866+
// @ts-expect-error - despite TS2526, it still infers correctly
867+
public static select<T extends Model = InstanceType<this>>(columns: MaybeArray<string>): T {
852868
return this.newQuery<T>().select(columns);
853869
}
854870

@@ -874,7 +890,8 @@ export default class BuildsQuery extends HasAttributes {
874890
*
875891
* @see BuildsQuery.prototype.has
876892
*/
877-
public static has<T extends Model>(relations: MaybeArray<string>): T {
893+
// @ts-expect-error - despite TS2526, it still infers correctly
894+
public static has<T extends Model = InstanceType<this>>(relations: MaybeArray<string>): T {
878895
return this.newQuery<T>().has(relations);
879896
}
880897

@@ -900,7 +917,8 @@ export default class BuildsQuery extends HasAttributes {
900917
*
901918
* @see BuildsQuery.prototype.with
902919
*/
903-
public static with<T extends Model>(relations: MaybeArray<string>): T {
920+
// @ts-expect-error - despite TS2526, it still infers correctly
921+
public static with<T extends Model = InstanceType<this>>(relations: MaybeArray<string>): T {
904922
return this.newQuery<T>().with(relations);
905923
}
906924

@@ -924,7 +942,8 @@ export default class BuildsQuery extends HasAttributes {
924942
*
925943
* @see BuildsQuery.prototype.without
926944
*/
927-
public static without<T extends Model>(relations: MaybeArray<string>): T {
945+
// @ts-expect-error - despite TS2526, it still infers correctly
946+
public static without<T extends Model = InstanceType<this>>(relations: MaybeArray<string>): T {
928947
return this.newQuery<T>().without(relations);
929948
}
930949

@@ -950,7 +969,8 @@ export default class BuildsQuery extends HasAttributes {
950969
*
951970
* @see BuildsQuery.prototype.scope
952971
*/
953-
public static scope<T extends Model>(scopes: MaybeArray<string>): T {
972+
// @ts-expect-error - despite TS2526, it still infers correctly
973+
public static scope<T extends Model = InstanceType<this>>(scopes: MaybeArray<string>): T {
954974
return this.newQuery<T>().scope(scopes);
955975
}
956976

@@ -981,7 +1001,8 @@ export default class BuildsQuery extends HasAttributes {
9811001
*
9821002
* @see BuildsQuery.prototype.orderBy
9831003
*/
984-
public static orderBy<T extends Model>(column: string, direction: Direction = 'asc'): T {
1004+
// @ts-expect-error - despite TS2526, it still infers correctly
1005+
public static orderBy<T extends Model = InstanceType<this>>(column: string, direction: Direction = 'asc'): T {
9851006
return this.newQuery<T>().orderBy(column, direction);
9861007
}
9871008

@@ -1005,7 +1026,8 @@ export default class BuildsQuery extends HasAttributes {
10051026
*
10061027
* @see BuildsQuery.prototype.orderByDesc
10071028
*/
1008-
public static orderByDesc<T extends Model>(column: string): T {
1029+
// @ts-expect-error - despite TS2526, it still infers correctly
1030+
public static orderByDesc<T extends Model = InstanceType<this>>(column: string): T {
10091031
return this.newQuery<T>().orderByDesc(column);
10101032
}
10111033

@@ -1031,7 +1053,8 @@ export default class BuildsQuery extends HasAttributes {
10311053
*
10321054
* @see BuildsQuery.prototype.latest
10331055
*/
1034-
public static latest<T extends Model>(column?: string): T {
1056+
// @ts-expect-error - despite TS2526, it still infers correctly
1057+
public static latest<T extends Model = InstanceType<this>>(column?: string): T {
10351058
return this.newQuery<T>().latest(column);
10361059
}
10371060

@@ -1057,7 +1080,8 @@ export default class BuildsQuery extends HasAttributes {
10571080
*
10581081
* @see BuildsQuery.prototype.oldest
10591082
*/
1060-
public static oldest<T extends Model>(column = 'created_at'): T {
1083+
// @ts-expect-error - despite TS2526, it still infers correctly
1084+
public static oldest<T extends Model = InstanceType<this>>(column = 'created_at'): T {
10611085
return this.newQuery<T>().oldest(column);
10621086
}
10631087

@@ -1086,7 +1110,8 @@ export default class BuildsQuery extends HasAttributes {
10861110
*
10871111
* @see BuildsQuery.prototype.offset
10881112
*/
1089-
public static offset<T extends Model>(count: number): T {
1113+
// @ts-expect-error - despite TS2526, it still infers correctly
1114+
public static offset<T extends Model = InstanceType<this>>(count: number): T {
10901115
return this.newQuery<T>().offset(count);
10911116
}
10921117

@@ -1112,7 +1137,8 @@ export default class BuildsQuery extends HasAttributes {
11121137
*
11131138
* @see BuildsQuery.prototype.skip
11141139
*/
1115-
public static skip<T extends Model>(count: number): T {
1140+
// @ts-expect-error - despite TS2526, it still infers correctly
1141+
public static skip<T extends Model = InstanceType<this>>(count: number): T {
11161142
return this.newQuery<T>().skip(count);
11171143
}
11181144
}

src/Calliope/Concerns/CallsApi.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export default class CallsApi extends BuildsQuery {
173173
*
174174
* @return {Promise<Model|ModelCollection<Model>>}
175175
*/
176-
// @ts-expect-error - we know in reality this is in fact a Model
176+
// @ts-expect-error - despite TS2526, it still infers correctly
177177
public async get<T extends Model = this>(
178178
queryParameters?: QueryParams | Record<string, unknown>
179179
): Promise<ModelCollection<T> | T> {
@@ -188,7 +188,8 @@ export default class CallsApi extends BuildsQuery {
188188
*
189189
* @see CallsApi.prototype.get
190190
*/
191-
public static async get<T extends Model>(
191+
// @ts-expect-error - despite TS2526, it still infers correctly
192+
public static async get<T extends Model = InstanceType<this>>(
192193
queryParameters?: QueryParams | Record<string, unknown>
193194
): Promise<ModelCollection<T> | T> {
194195
return new this().get<T>(queryParameters);
@@ -201,7 +202,7 @@ export default class CallsApi extends BuildsQuery {
201202
*
202203
* @return
203204
*/
204-
// @ts-expect-error - we know in reality this is in fact a Model
205+
// @ts-expect-error - despite TS2526, it still infers correctly
205206
public async post<T extends Model = this>(data: Attributes | FormData): Promise<T> {
206207
return this.call('post', data)
207208
.then(responseData => this.getResponseModel<T>(this.getDataFromResponse(responseData)));
@@ -214,7 +215,7 @@ export default class CallsApi extends BuildsQuery {
214215
*
215216
* @return
216217
*/
217-
// @ts-expect-error - we know in reality this is in fact a Model
218+
// @ts-expect-error - despite TS2526, it still infers correctly
218219
public async put<T extends Model = this>(data: Attributes | FormData): Promise<T> {
219220
return this.call('put', data)
220221
.then(responseData => this.getResponseModel<T>(this.getDataFromResponse(responseData)));
@@ -227,7 +228,7 @@ export default class CallsApi extends BuildsQuery {
227228
*
228229
* @return
229230
*/
230-
// @ts-expect-error - we know in reality this is in fact a Model
231+
// @ts-expect-error - despite TS2526, it still infers correctly
231232
public async patch<T extends Model = this>(data: Attributes | FormData): Promise<T> {
232233
return this.call('patch', data)
233234
.then(responseData => this.getResponseModel<T>(this.getDataFromResponse(responseData)));
@@ -241,7 +242,7 @@ export default class CallsApi extends BuildsQuery {
241242
*
242243
* @return {Promise<boolean>}
243244
*/
244-
// @ts-expect-error - we know in reality this is in fact a Model
245+
// @ts-expect-error - despite TS2526, it still infers correctly
245246
public async delete<T extends Model = this>(data?: Attributes | FormData): Promise<T> {
246247
return this.call('delete', data)
247248
.then(responseData => this.getResponseModel<T>(this.getDataFromResponse(responseData)));

src/Calliope/Model.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ export default class Model extends SoftDeletes implements HasFactory {
174174
/**
175175
* Call the factory fluently from the model.
176176
*/
177-
public static factory<T extends Model>(times = 1): FactoryBuilder<T> {
177+
// @ts-expect-error - despite TS2526, it still infers correctly
178+
public static factory<T extends Model = InstanceType<this>>(times = 1): FactoryBuilder<T> {
178179
return new FactoryBuilder(this as unknown as new (attributes?: Attributes) => T).times(times);
179180
}
180181

@@ -183,7 +184,8 @@ export default class Model extends SoftDeletes implements HasFactory {
183184
*
184185
* @return {Promise<Model|ModelCollection<Model>>}
185186
*/
186-
public static async all<T extends Model>(): Promise<ModelCollection<T>> {
187+
// @ts-expect-error - despite TS2526, it still infers correctly
188+
public static async all<T extends Model = InstanceType<this>>(): Promise<ModelCollection<T>> {
187189
let response = await new this().get<T>();
188190

189191
if (response instanceof Model) {
@@ -259,7 +261,8 @@ export default class Model extends SoftDeletes implements HasFactory {
259261
*
260262
* @see Model.prototype.find
261263
*/
262-
public static async find<T extends Model>(id: number | string): Promise<T> {
264+
// @ts-expect-error - despite TS2526, it still infers correctly
265+
public static async find<T extends Model = InstanceType<this>>(id: number | string): Promise<T> {
263266
return new this().find<T>(id);
264267
}
265268

@@ -286,7 +289,8 @@ export default class Model extends SoftDeletes implements HasFactory {
286289
*
287290
* @see Model.prototype.findMany
288291
*/
289-
public static async findMany<T extends Model>(ids: (number | string)[]): Promise<ModelCollection<T>> {
292+
// @ts-expect-error - despite TS2526, it still infers correctly
293+
public static async findMany<T extends Model = InstanceType<this>>(ids: (number | string)[]): Promise<ModelCollection<T>> {
290294
return new this().findMany<T>(ids);
291295
}
292296

0 commit comments

Comments
 (0)