Hookyns / tst-reflect

Advanced TypeScript runtime reflection system
MIT License
338 stars 11 forks source link

getCtor returns undefined when class property refers to another class that is defined after it #50

Closed avin-kavish closed 1 year ago

avin-kavish commented 2 years ago

This doesn't work,

@entity
export class Cat {
  id = 0
  toys: Toy[] = []
}

@entity
export class Toy {
  id = 0
}

const type = getType<Toy>()
await type.getCtor()  // undefined

This works,

@entity
export class Toy {
  id = 0
}

@entity
export class Cat {
  id = 0
  toys: Toy[] = []
}

const type = getType<Toy>()
await type.getCtor()  // [class Toy]

It's the toys: Toy[] = [] line causing the issue, it works when I comment it out. It looks like it only happens for array types, Toy[]. just a direct reference works fine.

Hookyns commented 2 years ago

@avin-kavish

It works for me.

import { getType } from "tst-reflect";

function entity(_: any)
{
}

@entity
export class Cat
{
    id = 0;
    toys: Toy[] = [];
}

@entity
export class Toy
{
    id = 0;
}

const type = getType<Toy>();
type.getCtor().then(ctor => console.log(ctor)); // It prints [class Toy]; working with Cat class too.

Can you send repro, eg. on StackBlitz?

avin-kavish commented 2 years ago

What I did is more like this. The link is not running but I think you can check the generated code.

Hookyns commented 2 years ago

Okay, there are three issues.

/**
 * @reflect
 */
export function entity<TType extends Function>(Class: TType) {
    const typeT = getType<TType>();
    console.log(typeT.name, Class);
}

I've already fixed the issue with decorators (in tst-reflect-transformer@0.9.13) so you can use the solution from the second point. Meanwhile, I will fix the issue from the first point, but you cannot use it in decorator anyway.

avin-kavish commented 2 years ago

Alright. Actually, 2nd point is not a problem. I did it that way just for the stackblitz example. In my actual implementation I push it to a container and later once all the modules are loaded, I check the types.

/**
 * @reflect
 */
export function entity<TType extends Constructor>(_: any) {
  const typeInfo = getType<TType>()
  EntityTypeStore.push(typeInfo)
}
avin-kavish commented 2 years ago

It's happening here also. https://stackblitz.com/edit/tst-reflect-issue-49-htnd32?file=package.json,index.ts

avin-kavish commented 2 years ago

Happened again. This time seemingly random, class next to it gets imported just fine.

Hookyns commented 2 years ago

Fixed in v1. Not in the current version.