kristiandupont / kanel

Generate Typescript types from Postgres
https://kristiandupont.github.io/kanel/
MIT License
881 stars 62 forks source link

kanel schema aware Identifiers #588

Open aq1018 opened 4 months ago

aq1018 commented 4 months ago

The default generateIdentifierType generates Identifiers like this:

/** Identifier type for Product */
export type ProductId = number & { __brand: 'ProductId' };

When using multiple schemas, it's is possible that two schemas will contain tables with the same name. To make the Identifier more strict, it probably should include the schema name as well.

Such as:

/** Identifier type for Public.Product */
export type ProductId = number & { __brand: 'Public.ProductId ' };

I worked around this issue by implementing a custom generateIdentifierType function like so:

// generate Schema Aware Identifiers
function generateIdentifierType(column, details) {
  return {
    declarationType: 'typeDeclaration',
    name: pascalCase(`${details.name}_${column.name}`),
    exportAs: 'named',
    typeDefinition: [
      `number & { __brand: '${details.schemaName}.${details.name}.${column.name}' }`,
    ],
    comment: [`Identifier type for ${details.schemaName}.${details.name}`],
  }
}

This creates something like this:

// In `term_life/Product.ts`

/** Identifier type for term_life.product */
export type ProductId = number & { __flavor?: 'term_life.product.id' };

// In `income_protection/Product.ts`
/** Identifier type for income_protection.product */
export type ProductId = number & { __flavor?: 'income_protection.product.id' };
kristiandupont commented 4 months ago

You are absolutely right, this is a bug. I will update this.