A problem with typescript version 4
Hi, objection.js is a great tool. I am using latest version of knex and typescript, so want to use objection@next but it is throwing error:
throw e;
^
RangeError: Maximum call stack size exceeded
at compareSignaturesRelated (\node_modules\typescript\lib\tsc.js:50982:27)
at signatureRelatedTo (\node_modules\typescript\lib\tsc.js:52833:24)
at signaturesRelatedTo (\node_modules\typescript\lib\tsc.js:52776:39)
at structuredTypeRelatedToWorker (\node_modules\typescript\lib\tsc.js:52309:39)
at structuredTypeRelatedTo (\node_modules\typescript\lib\tsc.js:51954:30)
at recursiveTypeRelatedTo (\node_modules\typescript\lib\tsc.js:51930:53)
at isRelatedTo (\node_modules\typescript\lib\tsc.js:51527:34)
at isPropertySymbolTypeRelated (\node_modules\typescript\lib\tsc.js:52488:24)
at propertyRelatedTo (\node_modules\typescript\lib\tsc.js:52520:31)
at propertiesRelatedTo (\node_modules\typescript\lib\tsc.js:52708:43)
package.json:
"objection": "^3.0.0-alpha.5",
"typescript": "^4.4.4"
Which version of objection.js and typescript should I use?
Objection v3 is still alpha version meaning that it is still not complete, you can use version 2.2.15 which is stable and I use typescript version 4.3.5
Objection v3 is still alpha version meaning that it is still not complete, you can use version 2.2.15 which is stable and I use typescript version 4.3.5
It still does not work, it throws error:
node_modules/objection/typings/objection/index.d.ts:1839:12 - error TS2709: Cannot use namespace 'Knex' as a type.
1839 (knex: Knex, modelClasses: AnyModelConstructor[]): Promise<void>;
~~~~
I fixed by adding skipLibCheck in tsconfig.json but it is not a good solution:
// tsconfig.js
"compilerOptions": {
"skipLibCheck": true
}
@vh-dao Please check upgrading guide for Knex, I think you are using latest version in a wrong way.
Can you try objection next, knex 0.95, ts 4.4 and share code which is throwing an error?
I'm having this issue with circular dependencies in relationMappings. Because I am using ESM the require loop solution does not work.
import { Model } from 'objection'
import { AuthenticationMethod } from './AuthenticationMethod';
export class Account extends Model {
id: string
email: string
static get tableName() {
return 'accounts';
}
static relationMappings() {
return {
authenticationMethods: {
relation: Model.HasManyRelation,
modelClass: AuthenticationMethod,
join: {
from: 'accounts.id',
to: 'authentication_methods.account_id'
}
}
}
}
}
import { Model} from 'objection'
import { Account} from './Account'
export class AuthenticationMethod extends Model {
static get tableName() {
return 'authentication_methods'
}
static get relationMappings() {
return {
account: {
relation: Model.BelongsToOneRelation,
modelClass: Account,
join: {
from: 'authentication_methods.account_id',
to: 'accounts.id'
}
}
}
}
}
➜ dev-server git:(master) ✗ tsc
/usr/lib/node_modules/typescript/lib/tsc.js:92656
throw e;
^
RangeError: Maximum call stack size exceeded
at String.replace (<anonymous>)
at /usr/lib/node_modules/typescript/lib/tsc.js:51887:90
at Array.map (<anonymous>)
at recursiveTypeRelatedTo (/usr/lib/node_modules/typescript/lib/tsc.js:51887:62)
at isRelatedTo (/usr/lib/node_modules/typescript/lib/tsc.js:51527:34)
at typeArgumentsRelatedTo (/usr/lib/node_modules/typescript/lib/tsc.js:51834:39)
at relateVariances (/usr/lib/node_modules/typescript/lib/tsc.js:52341:34)
at structuredTypeRelatedToWorker (/usr/lib/node_modules/typescript/lib/tsc.js:52289:46)
at structuredTypeRelatedTo (/usr/lib/node_modules/typescript/lib/tsc.js:51954:30)
at recursiveTypeRelatedTo (/usr/lib/node_modules/typescript/lib/tsc.js:51930:53)
➜ dev-server git:(master) ✗ tsc -v
Version 4.4.4
"dependencies": {
"knex": "^0.95.12",
"objection": "^3.0.0-rc.2"
},
Edit: It doesn't seem to necessarily be a circular dependency problem, because removing the parent relationship from the child does not solve the problem.
Edit2: Removing any attributes from the child (e.g. id: string) removes the compilation error but obviously will result in runtime errors.
Can you try objection next, knex 0.95, ts 4.4 and share code which is throwing an error?
The error I reported are object@next and typescript v4.4
package.json:
"objection": "^3.0.0-alpha.5",
"typescript": "^4.4.4"
I can't reproduce this. I really need a working reproduction or there's nothing I can do. Latest objection@next is now tested agains typescript 4.4.4 and all tests pass.
Reproduction: https://github.com/stefanvanherwijnen/objection-repro-2132
You are not running typescript in strict mode. Add strict: true to tsconfig.
I'm running into this issue with the released version of 3.0.0
@koskimas are you saying that objection 3 requires strict: true to work properly with typescript? Is that documented anywhere? It seems like a pretty significant limitation.
I don't think strict is required, but it will point out any errors in your model files. In my case the solution was to properly define the properties with the ! operator, e.g. id!: string
Edit: Actually, strict is required for compilation.
@stefanvanherwijnen is it documented anywhere that strict: true must be specified in the tsconfig? I'm not currently using strict mode with versions prior to V3 and didn't have any issues.
No I don't think so. But in my case without strict: true I get the error which this issue is about, with it I don't. It might be introduced in V3 but I think @koskimas should clear this up or document it.
This issue should be reopened. The culprit is one of these typings:
type PartialModelObject<T extends Model> = {
[K in NonFunctionPropertyNames<T>]?: Defined<T[K]> extends Model
? T[K]
: Defined<T[K]> extends Array<infer I>
? I extends Model
? I[]
: Expression<T[K]>
: Expression<T[K]>;
};
type PartialModelGraph<M, T = M & GraphParameters> = {
[K in NonFunctionPropertyNames<T>]?: Defined<T[K]> extends Model
? PartialModelGraph<Defined<T[K]>>
: Defined<T[K]> extends Array<infer I>
? I extends Model
? PartialModelGraph<I>[]
: Expression<T[K]>
: Expression<T[K]>;
};
when I change one of them to any the project compiles fine. But I couldn't figure out which code line or model triggers it yet.
INFO:
node: 16.13.0
knex: 0.95.14
objection: 3.0.0
typescript: 4.5.4
@koskimas I think the issue is caused by NonFunctionPropertyNames including QueryBuilderType. It should go away by excluding QueryBuilderType in PartialModelObject and PartialModelGraph:
type PartialModelObject<T extends Model> = {
[K in Exclude<NonFunctionPropertyNames<T>, 'QueryBuilderType'>]?: Defined<T[K]> extends Model
? T[K]
: Defined<T[K]> extends Array<infer I>
? I extends Model
? I[]
: Expression<T[K]>
: Expression<T[K]>;
};
I'm not sure why I also needed T extends any for PartialModelGraph, probably some weird union issue:
type PartialModelGraph<M, T = M & GraphParameters> = T extends any ? {
[K in Exclude<NonFunctionPropertyNames<T>, 'QueryBuilderType'>]?: Defined<T[K]> extends Model
? PartialModelGraph<Defined<T[K]>>
: Defined<T[K]> extends Array<infer I>
? I extends Model
? PartialModelGraph<I>[]
: Expression<T[K]>
: Expression<T[K]>;
} : never;
Thank you @Linksku! Great work! I'll try this soon and release a new version if it works!
That fix is now implemented in 3.0.1. Please try it out and report back to me if the issue is gone
Thanks! I still need T extends any to avoid Maximum call stack size exceeded. Maybe my types are just weird and it works for other people without that
Hmm... That's weird. Could you create a reproduction for me? For some reason I'm unable to reproduce any of these typescript problems. Probably due to my tsconfig being different.
Hi! Same as @Linksku, I also need to wrap the declaration of PartialModelGraph with T extends any ? ... : never. If I don't do this, the types of "nested" models (from relationMappings) in a model graph are not inferred by TypeScript. However, I do not face a Maximum call stack size exceeded error when compiling my project without this fix:
type PartialModelGraph<M, T = M & GraphParameters> = T extends any ? {
[K in DataPropertyNames<T>]?: Defined<T[K]> extends Model
? PartialModelGraph<Defined<T[K]>>
: Defined<T[K]> extends Array<infer I>
? I extends Model
? PartialModelGraph<I>[]
: Expression<T[K]>
: Expression<T[K]>;
} : never;
@koskimas: Cloud you release a new version with the T extends any ? ... : never fix? I would be very grateful! :-)
FYI: It does not matter if I set strict: true or strict: false in my tsconfig.json file - in both cases, I still need the T extends any ? ... : never fix.
Package versions:
typescript: 4.5.4
objection: 3.0.1
knex: 0.95.15
I was getting the same maximum stack error with typescript 4.5.5, no direct errors were showing until i reduced the project to one model i'm getting
permission.model.ts:6:22 - error TS2321: Excessive stack depth comparing types 'UpsertGraphMethod<?>' and 'UpsertGraphMethod<?>'.
i also can no longer chain .throwIfNotFound() and manually have to check:
await Activity
.query(trx)
.findById(req.params.id)
// .throwIfNotFound({message: 'Activity not found.'}) no longer works
.then(async (activity: Activity | undefined) => {
if (!activity)
throw new NotFoundError({message: 'Activity not found.'})
Hi, I have the same issue. Also fixed with the T extends any ? ... : never fix. Please can you release a new version with this included?
I am getting the same error on Typescript 4.5.5 as well. I was able to get rid of the problem by setting strictNullChecks: false in tsconfig.json as mentioned in related issue but it's just a temporary fix.
Hey, Can we please implement the fix from @Linksku ? It works for me and stops all my projects breaking...