kanel icon indicating copy to clipboard operation
kanel copied to clipboard

Reference primary keys are not using the imported type

Open janmeier opened this issue 4 years ago • 4 comments

Here, the primary key on bar references the primary key on foo

CREATE TABLE foo (id uuid primary key);
CREATE TABLE bar (id uuid primary key references foo(id));

Foo.ts

export type FooId = string & { __flavor?: 'foo' }; ;

export default interface Foo {
  /** Primary key. Index: foo_pkey */
  id: FooId;
}

export interface FooInitializer {
  /** Primary key. Index: foo_pkey */
  id: FooId;
}

export const tableName = 'foo'

Bar.ts

import { FooId } from './Foo';

export type BarId = string & { __flavor?: 'bar' };

export default interface Bar {
  /** Primary key. Index: bar_pkey */
  id: BarId;
}

export interface BarInitializer {
  /** Primary key. Index: bar_pkey */
  id: BarId;
}

Notice how FooId is imported, but is not actually used, which causes the typescript compiler to complain.

janmeier avatar Jan 15 '21 13:01 janmeier

I think this is a duplicate of #15? It's a bug for sure, and apparently one that I should get fixed as this seems to be something people do. I don't personally use this pattern and I am curious as to what you think the most correct solution is. Should Bar.id be a BarId, a FooId or a whole new thing like a FooOrBarId? What is the semantic relation?

kristiandupont avatar Jan 15 '21 14:01 kristiandupont

I think the issues are subtly different - #15 has a composite primary key, while this example has a single uuid primary key. In the other issue, the generated model is trying to import something that doesn't exist, while here it's generating an unused import. So it's actually importing the type from the referenced model, but not using it.

To make matters a bit more concrete (sorry for the abstraction, I was just trying to make the example as small as possible :))

CREATE TABLE profile (id uuid primary key);
CREATE TABLE profile_settings (id uuid primary key references profile(id));
import { ProfileId } from './Profile';

export type ProfileSettingsId = string & { __flavor?: 'ProfileSettings' };

export default interface ProfileSettings {
  /** Primary key. Index: profile_settings_pkey */
  id: ProfileSettingsId;
}

export interface ProfileSettingsInitializer {
  /** Primary key. Index: profile_settings_pkey */
  id: ProfileSettingsId;
}

In this case, I would expect ProfileSettings.id to be a ProfileId, since it's a parent:child relation

janmeier avatar Jan 18 '21 13:01 janmeier

Ah you are right, I was a bit too quick there. Thank you for the explanation. I will try fixing this hopefully soonish :-)

kristiandupont avatar Jan 19 '21 07:01 kristiandupont

+1

Scott-Allen-Mind-Gyn avatar Oct 08 '21 14:10 Scott-Allen-Mind-Gyn

This should finally be addressed :-)

There is a premajor version out that should fix this issue. There are significant breaking changes though, and the API is not final so feel free to experiment if you like. The documentation is work in progress still, you can start here: https://github.com/kristiandupont/kanel/blob/v3/docs/configuring.md

kristiandupont avatar Aug 16 '22 14:08 kristiandupont