-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
generate 'schema' and 'ts interface' in one swoop #25
Comments
maybe i can make something happen if i flip this upside down, eh? interface UserRow {
id: string
email: string
nickname: string
}
const userSchema = tableSchema<UserRow>({
id: {primary: true, unique: true, type: String},
email: {type: String},
nickname: {type: String},
}) that could almost be done.. but i don't think we can get the compiler to enforce the let me know if i'm barking up the wrong tree here, just curious about your thoughts and opinions |
There isn't much support in TypeScript for reflection and I believe the creators of the language have even said that it was a mistake to even upon up the slightest for it (people will always want more, further complicating the language and how its used). But it's a nice idea and perhaps the winds are changing. Last time I looked, it was simply not feasible without tooling for pre-processing. |
i think it may be doable using conditional types.. i'll see if i can look into it! at the very least we should leverage generics so we can type the query results, we can certainly do that much today // bad: without a generic type
await query`select * from users where balance >= ${minimum}`
//> returned type: any
// good: we should allow an optional generic type
await query<UserRow>`select * from users where balance >= ${minimum}`
//> returned type: UserRow[] of course that's my sugar, but the core i'll keep looking into about whether conditional types can allow us to provide a single source of truth for both schema and interface.. or at the very least, if we have to define it two ways, at least have the typescript compiler enforce a match. cheers 🍻 |
But using generics this way is not type-safe; why not just: await query`select ...` as UserRow. If we wanted a more strict typing mechanism, columns would also need to be typecast on the query side (i.e. "select a::int, b::text") and this requires a schema-aware query builder. That is, we would need some interface reflection and code generation or metaprogramming to pull this off. |
i'm not sure what you mean, that generics aren't type-safe? it doesn't matter anyways:
i think i realize that you're right! it's simpler and there's no benefit to the generic in this case! i still have hopes i can leverage some fancy fancy typescript advanced features to create some kind of 1:1 enforcement between a typescript interface and the relevant schema. i think there will still be repetition, but i hope we can at least achieve compiler enforcement of consistency. i'll let you know how it goes! i'm also going to see if i can implement this tagged-template sugar :) cheers! |
In languages that provide compile-time metaprogramming such as Rust, you can easily write a macro to accomplish this. But that's still an open issue. cheers |
Since you can now provide a type for |
i'm trying to eliminate maintenance. ALL OF IT!
i was wondering if you have a recommendation for a good way i could generate both a table schema and also a matching typescript interface at the same time, or at least make sure these are synced up in lock-step
also, looking at the readme, i'm not clear: are functions like
query
using typescript generics? can we pass in a the type signature for the result, so that the results come back with full typings?i'm imagining some idealized situation like along these lines (using my imaginary sugar from issue #24 :)
do you have any advice, or am i wandering into
typeorm
territory?thanks 🍻
The text was updated successfully, but these errors were encountered: