-
Notifications
You must be signed in to change notification settings - Fork 641
Closed
Description
In the Custom query builder guide, extending the query builder in TypeScript is achieved with the following workaround:
import {
Model,
Page,
QueryBuilder,
} from 'objection'
export class MyModel extends Model {
static get QueryBuilder() {
return class MyModelCustomQueryBuilder<M extends Model, R = M[]> extends QueryBuilder<M, R> {
ArrayQueryBuilderType!: MyModelCustomQueryBuilder<M, M[]>;
SingleQueryBuilderType!: MyModelCustomQueryBuilder<M, M>;
NumberQueryBuilderType!: MyModelCustomQueryBuilder<M, number>;
PageQueryBuilderType!: MyModelCustomQueryBuilder<M, Page<M>>;
constructor(...args: [arg: any]) { // 1-element tuple, ugly hack/workaround
super(...args)
this.onBuild(builder => {
const { withArchived = false } = builder.context()
if (!withArchived) {
builder.andWhere('is_archived', false)
}
})
}
}
}
}It works, but the guide also suggests just overriding the query static method since I am not adding methods to the custom query builder and only modifying the query behavior (specifically, automatically adding the is_archived = false WHERE condition on all queries by default).
I cannot, however, make the static query override pass the TypeScript type-check. Here's my latest attempt:
import {
Model,
Page,
QueryBuilder,
} from 'objection'
export class MyModel extends Model {
// this would've been shorter, but it wouldn't compile due to https://github.com/microsoft/TypeScript/issues/4628 :(
static query(...args: any[]) {
return super.query<MyModel>(...args)
.onBuild(builder => {
const { withArchived = false } = builder.context()
if (!withArchived) {
builder.andWhere('is_archived', false)
}
})
}
}The error from the TypeScript compiler:
Class static side 'typeof MyModel' incorrectly extends base class static side 'typeof Model'.
The types returned by 'query(...)' are incompatible between these types.
Type 'QueryBuilder<MyModel, MyModel[]>' is not assignable to type 'QueryBuilderType<M>'.
Type 'QueryBuilder<MyModel, MyModel[]>' is not assignable to type 'QueryBuilder<M, M[]>'.
The types returned by 'findById(...).execute()' are incompatible between these types.
Type 'Promise<MyModel>' is not assignable to type 'Promise<M>'.
Type 'MyModel' is not assignable to type 'M'.
'M' could be instantiated with an arbitrary type which could be unrelated to 'MyModel'.ts(2417)
My question is:
- Is there a way to make this work? Am I missing a type-coercion trick on my code?
- If not, is the Model base class static query method typing incorrect (or can it be improved to make this work)?
Or is there nothing that can be done because this is just a natural limitation of microsoft/TypeScript#4628?
Metadata
Metadata
Assignees
Labels
No labels