drizzle-orm
drizzle-orm copied to clipboard
[BUG]: `"composite" true` and Yarn workspace prevents `pgTable` from being compiled
What version of drizzle-orm
are you using?
0.26.1
What version of drizzle-kit
are you using?
0.18.1
Describe the Bug
TL;DR
TypeScript can't compile simple schema.ts
file with users
example table when using "composite": true
in tsconfig.json
Longer version
I have Yarn workspace with two packages, let's call them backend
and frontend
.
Naturally, frontend
depends on backend
. For that to work, backend
's tsconfig.json
must include "composite": true
option.
backend
uses drizzle-orm
internally for migrations and I would like to use a standalone schema.ts
file where all of the tables would be declared. With such setup, I would need to export said tables to use them elsewhere in the code.
This is the moment where export
before the users
table declaration makes TypeScript compiler think that anyone can import users
(type of which depends on inference of drizzle-orm
package), even outside of the backend
package. Due to lack of export(package)
in TypeScript, this leads to compiler errors.
schema.ts
import { pgTable, serial, text, varchar } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial("id").primaryKey(),
fullName: text("full_name"),
phone: varchar("phone", { length: 256 }),
});
- error TS2742: The inferred type of 'users' cannot be named without a reference to '../../node_modules/drizzle-orm/db.d-2eb7c122'. This is likely not portable. A type annotation is necessary.
3 export const users = pgTable("users", {
~~~~~
Found 1 error.
error Command failed with exit code 1.
Expected behavior
Everything compiles just fine.
I found possible workarounds, but none of them are optimal: https://github.com/microsoft/TypeScript/issues/47663#issuecomment-1519138189
Environment & setup
No response
@TmLev for the time being, have you settled for an workaround, and if so, which? I am facing the same issue.
@alexanderniebuhr I haven't, no. Had to completely remove Drizzle from my backend
, sadly. Have you tried the workaround number 3? It seems promising.
UPD: Tried it, doesn't work.
Importing the requested file directly
import * as _drizzle from '../../../../node_modules/drizzle-orm/select.types.d-e43b2599';
turns the error to silent
I don't think you should do that, but if it fixes the error...
An alternative is to create your own mysqlTable
| pgTable
method
with mysql
import { mysqlTable as mysqlTableDrizzle } from 'drizzle-orm/mysql-core';
export type Table<
TableName extends string,
TConfigMap extends Record<string, AnyMySqlColumnBuilder>,
> = MySqlTableWithColumns<{
name: TableName;
schema: undefined;
columns: BuildColumns<TableName, TConfigMap>;
}>;
export const mysqlTable = <
TableName extends string,
TConfigMap extends Record<string, AnyMySqlColumnBuilder>,
>(
table: TableName,
columns: TConfigMap,
extraConfig?: (
self: BuildColumns<TableName, TConfigMap>,
) => MySqlTableExtraConfig,
): Table<TableName, TConfigMap> =>
mysqlTableDrizzle(table, columns, extraConfig);
An alternative is to create your own
mysqlTable
|pgTable
method
While this sounds promising, I really think it should be possible to fix in the lib layer. Isn't it?
it doesn't seem to be an issue related to drizzle
so unfortunately no
Since it seems that it can be fixed with changes of the type of exports in the lib code, according to the upstream issue comments, I would think these changes can be made to drizzle
to fix it.
If the following statement is true, I think it can be fixed in drizzle
side, with changing this pattern.
Any npm package whose types reference another npm package's type will generate the error
It's just a way to use workaround 2 as described here https://github.com/microsoft/TypeScript/issues/47663#issuecomment-1519138189
That's correct, but which other package is drizzle
referencing the types from. If we know this, we should just be able to install it in addition.
I just accidentally found an workaround, adding the line to any file with the error, fixes it for me. @TmLev can you validate?
import type { PgTableWithColumns, TableConfig } from 'drizzle-orm/pg-core'
type unused = PgTableWithColumns<TableConfig>
Could you supply a minimal reproduction repo? Would like to take a look at it :)
I will, in a few hours
Could you supply a minimal reproduction repo?
@pkerschbaum sure!
- https://stackblitz.com/github/alexanderniebuhr/drizzle-repro
- https://github.com/alexanderniebuhr/drizzle-repro
You can use following command:
pnpm --filter db start
The file with the issue is:
packages/db/src/schema/products.ts
I just accidentally found an workaround, adding the line to any file with the error, fixes it for me. @TmLev can you validate?
import type { PgTableWithColumns, TableConfig } from 'drizzle-orm/pg-core' type unused = PgTableWithColumns<TableConfig>
I can confirm that this fixes the issue for me.
I finally looked into it and workaround #3.1 of https://github.com/microsoft/TypeScript/issues/47663#issuecomment-1519138189 could also be applied (PgTableWithColumns
must be made available by exporting it), that would fix it in the library itself.
See https://github.com/pkerschbaum/drizzle-repro/compare/main...fix/patch-for-drizzle-orm for the changes.
I would suggest that drizzle-orm applies this to easen the burden of pnpm users.
I've got a pretty similar error for relations.
Literally adding export
in front of Relations
, One
, and Many
inside query-promise.d
resolved the issue.
export declare class Relations<TTableName extends string = string, TConfig extends Record<string, Relation> = Record<string, Relation>> {
readonly table: AnyTable<{
name: TTableName;
}>;
readonly config: (helpers: TableRelationsHelpers<TTableName>) => TConfig;
static readonly [entityKind]: string;
readonly $brand: 'Relations';
constructor(table: AnyTable<{
name: TTableName;
}>, config: (helpers: TableRelationsHelpers<TTableName>) => TConfig);
}
export declare class One<TTableName extends string = string, TIsNullable extends boolean = boolean> extends Relation<TTableName> {
readonly config: RelationConfig<TTableName, string, AnyColumn<{
tableName: TTableName;
}>[]> | undefined;
readonly isNullable: TIsNullable;
static readonly [entityKind]: string;
protected $relationBrand: 'One';
constructor(sourceTable: Table, referencedTable: AnyTable<{
name: TTableName;
}>, config: RelationConfig<TTableName, string, AnyColumn<{
tableName: TTableName;
}>[]> | undefined, isNullable: TIsNullable);
withFieldName(fieldName: string): One<TTableName>;
}
export declare class Many<TTableName extends string> extends Relation<TTableName> {
readonly config: {
relationName: string;
} | undefined;
static readonly [entityKind]: string;
protected $relationBrand: 'Many';
constructor(sourceTable: Table, referencedTable: AnyTable<{
name: TTableName;
}>, config: {
relationName: string;
} | undefined);
withFieldName(fieldName: string): Many<TTableName>;
}
@alexanderniebuhr had the same issue, fixed after I changed "moduleResolution" from "NodeNext" to "Node"
fixed after I changed "moduleResolution" from "NodeNext" to "Node"
Thanks for the info. However that is a change, not everyone can do!
I've got a pretty similar error for relations.
Literally adding
export
in front ofRelations
,One
, andMany
insidequery-promise.d
resolved the issue.export declare class Relations<TTableName extends string = string, TConfig extends Record<string, Relation> = Record<string, Relation>> { readonly table: AnyTable<{ name: TTableName; }>; readonly config: (helpers: TableRelationsHelpers<TTableName>) => TConfig; static readonly [entityKind]: string; readonly $brand: 'Relations'; constructor(table: AnyTable<{ name: TTableName; }>, config: (helpers: TableRelationsHelpers<TTableName>) => TConfig); } export declare class One<TTableName extends string = string, TIsNullable extends boolean = boolean> extends Relation<TTableName> { readonly config: RelationConfig<TTableName, string, AnyColumn<{ tableName: TTableName; }>[]> | undefined; readonly isNullable: TIsNullable; static readonly [entityKind]: string; protected $relationBrand: 'One'; constructor(sourceTable: Table, referencedTable: AnyTable<{ name: TTableName; }>, config: RelationConfig<TTableName, string, AnyColumn<{ tableName: TTableName; }>[]> | undefined, isNullable: TIsNullable); withFieldName(fieldName: string): One<TTableName>; } export declare class Many<TTableName extends string> extends Relation<TTableName> { readonly config: { relationName: string; } | undefined; static readonly [entityKind]: string; protected $relationBrand: 'Many'; constructor(sourceTable: Table, referencedTable: AnyTable<{ name: TTableName; }>, config: { relationName: string; } | undefined); withFieldName(fieldName: string): Many<TTableName>; }
We were able to fix the issue using this suggestion and locally patching drizzle-orm using pnpm patch
.
should be reopened, I don't think my PR fixed it completely.
Setting the following to false in ts.config
fixed it for me
"declaration": false,
"declarationMap": false,
"composite": false,
Setting the following to false in
ts.config
fixed it for me
Yes it does. But it should work with any setting. I need all of them to be true