diff --git a/tests/types/circularTypes.ts b/tests/types/circularTypes.ts new file mode 100644 index 0000000..dbe761b --- /dev/null +++ b/tests/types/circularTypes.ts @@ -0,0 +1,89 @@ +import { describe, expectTypeOf, it } from "vitest"; +import { defineEntity, defineField, defineIdField, Farstorm, OutputType } from "../../src/main"; + +describe('Types: circular references', () => { + const entityDefinitions = { + 'EntityA': defineEntity({ + fields: { + id: defineIdField(), + name: defineField('string', false), + a1: defineField('string', false), + a2: defineField('string', false), + a3: defineField('string', false), + a4: defineField('string', false), + a5: defineField('string', false), + a6: defineField('string', false), + a7: defineField('string', false), + a8: defineField('string', false), + a9: defineField('string', false), + a10: defineField('string', false), + a11: defineField('string', false), + a12: defineField('string', false), + a13: defineField('string', false), + a14: defineField('string', false), + a15: defineField('string', false), + a16: defineField('string', false), + a17: defineField('string', false), + a18: defineField('string', false), + a19: defineField('string', false), + }, + oneToMany: { + b: { entity: 'EntityB', inverse: 'a' }, + bOther: { entity: 'EntityB', inverse: 'anotherA' }, + }, + }), + 'EntityB': defineEntity({ + fields: { + id: defineIdField(), + name: defineField('string', false), + b1: defineField('string', false), + b2: defineField('string', false), + b3: defineField('string', false), + b4: defineField('string', false), + b5: defineField('string', false), + b6: defineField('string', false), + b7: defineField('string', false), + b8: defineField('string', false), + b9: defineField('string', false), + b10: defineField('string', false), + b11: defineField('string', false), + b12: defineField('string', false), + b13: defineField('string', false), + b14: defineField('string', false), + b15: defineField('string', false), + b16: defineField('string', false), + b17: defineField('string', false), + b18: defineField('string', false), + b19: defineField('string', false), + }, + manyToOne: { + a: { entity: 'EntityA', nullable: false }, + anotherA: { entity: 'EntityA', nullable: true }, + }, + }), + }; + + it('should still keep types even if recursing deeply', async () => { + type OrmOutput = OutputType; + + type BaseA = OrmOutput<'EntityA'>; + type BaseB = OrmOutput<'EntityB'>; + + type AtoB1 = Awaited[number]; + type BtoA1 = Awaited; + + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + + type AtoBOther = Awaited[number]; + type BtoAOther = NonNullable>; + + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + + type GetB = Awaited[number]; + type GetA = Awaited; + type DeepChainAtoB = GetB>>>>>>>>>>>>>>>>; + expectTypeOf().toEqualTypeOf(); + }); +}); \ No newline at end of file