wwwouter / typed-knex

A TypeScript wrapper for Knex.js
MIT License
112 stars 13 forks source link

TypeError when using innerJoinColumn #30

Closed rizky closed 3 years ago

rizky commented 3 years ago

Issue type:

[x] Question [x] Bug report [ ] Feature request [ ] Documentation issue

Database system/driver:

[x] Postgres [ ] MSSQL [ ] MySQL [ ] MariaDB [ ] SQLite3 [ ] Oracle [ ] Amazon Redshift

typed-knex version:

[x] latest [ ] @next [ ] 0.x.x (or put your version here)

Table definition

@Table("sites")
export class TableSites {
    @Column()
    public address?: string | null | undefined;
    @Column()
    public country?: string | null | undefined;
    @Column({ primary: true })
    public id: Id;
};

@Table("activities")
export class TableActivities {
    @Column()
    public description?: string | null | undefined;
    @Column({ primary: true })
    public id: Id;
    @Column()
    public siteId?: Id | null | undefined;
    @Column({ name: "siteId" })
    public site?: TableSites | null | undefined;
};

Code

knex.query(TableActivities).select('id', 'siteId').innerJoinColumn('site')

Error

TypeError:
     at Object.getMetadata (node_modules/reflect-metadata/Reflect.js:354:23)
     at Object.getTableMetadata (node_modules/@wwwouter/typed-knex/src/decorators.ts:46:20)
     at TypedQueryBuilder.joinColumn (node_modules/@wwwouter/typed-knex/src/typedKnex.ts:2141:34)
     at TypedQueryBuilder.innerJoinColumn (node_modules/@wwwouter/typed-knex/src/typedKnex.ts:1370:21)

It seems that reflect-metadata couldn't get design:type of propertyKey site, it returns undefined instead of TableSites. Did I configure Table definition correctly?

Using innerJoinTableOnFunction works perfectly fine.

wwwouter commented 3 years ago

"The decorator metadata feature is not meant to provide a full runtime type system, or a reflection-like feature." See https://github.com/microsoft/TypeScript/issues/9916

That's why you cannot use unions in your table definition classes.

Catching these errors and providing useful feedback has been challenging 😄

Because you will never select and object like site, you can either define it just as public site: TableSites; or if you want public site?: TableSites;

BTW: To be able to move this library closer to Knex itself, the innerJoinColumn and objects in table definition classes will probably need to be removed.

rizky commented 3 years ago

Got it! Thank you for your help and this amazing library with a lot of potential. Keep up the good work!