Specify the Typescript type for a column, specifically a String column
Problem
Is there a way to use a String column as an enum type without creating the enum type on the db? While the enum feature is useful, making changes will require new migrations which are not ideal for often-changing enum values. I have seen in other frameworks (see this Rails gem) that use a string column but limit the values that can be set to the column via an enum.
For example, given this enum that often changes:
enum FormFieldType {
Input
Textarea
Select
...
}
schema.prisma:
model FormField {
name String
type String @cast(FormFieldType)
}
This would cast a TS type (notice type key not a string):
type FormField = {
name: string;
type: FormFieldType;
}
This is also great when creating or updating the model where type column has an enum type, disallowing non-allowed values.
prisma.formField.create({ type: 'foo' }) // ts error
prisma.formField.create({ type: FormFieldType.Input }) // all good!
Suggested solution
Suggestion noted above. Allow a directive for the schema to specify the cast type. Another option is to override this in the options when initializing the PrismaClient class.
Alternatives
Noted above.
Additional context
There are probably some similarities to this issue: https://github.com/prisma/prisma/issues/3219. The ask here is to override the generated Typescript types that are generated through the schema.
This also applied to array string columns where a developer may want to set the values that are allowed to be set within the array. FormFieldType[] as an example.
Prisma does not support this functionality right now. A string is a string, and an enum is an enum. You could probably prevent adding unwanted values via a simple middleware, but that would not give you the type safety you are suggesting above unfortunately.
@janpio Agree, a middleware could be an option but will not solve the type-safety concerns. While I agree that a string is a string, database column types don't always translate well when it comes to typescript types (string literals, as an example, or number vs bigint/float).
We could solve this issue and this issue if there was an ability to override the types generated by the schema and give developers more flexibility on controlling the types.
(Might be worth creating a separate, explicit feature request issue for the idea "ability to override the types generated by the schema and give developers more flexibility on controlling the types" standalone @mmahalwy)
@janpio that's a good point. I will create a FR and tag you in it :)
Did anything ever come of this? I am running into this exact use case
adding an additional point here that having this ability would be greatly appreciated!
I'm running into this exact scenario. It would be very nice to be able to do something like this in a PostgreSQL db:
model XTable {
...
source SourceType? @db.String
}
enum SourceType {
extension
api
import
}
or as @mmahalwy mentioned:
source String @cast(SourceType)
Atm, @db.String is not possible, so Prisma assumes the SourceType enum is an enum in the DB, which I don't want it to be. In the DB, I want source to be source TEXT CHECK (source IN ('extension', 'api', 'import_list')).
Is there an alternative to achieve this behaviour?