MiNiMAL
MiNiMAL
Explore posts from servers
DTDrizzle Team
Created by MiNiMAL on 10/14/2023 in #help
Front to back end type inference with parameters sent via request
Hey there, I've been exploring using drizzle in a TRPC environment. This is probably a pipe dream, but ideally, our developers would be able to dynamically pass a findMany input and have the query's results inferred all the way to the front end.
// Front end
const { data } = trpc.tablename.get.useQuery({
where: { } // <== where clause options are dynamically inferred
with: { nestedEntities: true } // <== with clause options are dynamically inferred
})

console.log(data?.[0]?.nestedEntities)
// ^ This is valid when the with clause is provided to the hook, but will not if it's not there
// Front end
const { data } = trpc.tablename.get.useQuery({
where: { } // <== where clause options are dynamically inferred
with: { nestedEntities: true } // <== with clause options are dynamically inferred
})

console.log(data?.[0]?.nestedEntities)
// ^ This is valid when the with clause is provided to the hook, but will not if it's not there
The first issue I encountered is that there needs to be a translation layer for the where statements, as we cannot send drizzle operator functions over a request. To handle this, I built out a recursive layer for where statements at the root and also in any nested with and it works functionally very well (though is only strongly typed at the root layer). Example:
where: {
columnA: { equal_to: 123 },
or: [
columnB: { isNull: false },
columnA: { likeInsensitive: '%TRPC%' }
]
}
where: {
columnA: { equal_to: 123 },
or: [
columnB: { isNull: false },
columnA: { likeInsensitive: '%TRPC%' }
]
}
The above's operators and column names all have type inference/intellisense based on the DB model. The above turns into this on the backend:
where: (table, { and, eq, or, isNull, ilike }) =>
and(...[
eq(table['columnA'], 123),
or(...[
isNull(table['columnB']),
ilike(table['columnA'], '%TRPC%')
])
)
where: (table, { and, eq, or, isNull, ilike }) =>
and(...[
eq(table['columnA'], 123),
or(...[
isNull(table['columnB']),
ilike(table['columnA'], '%TRPC%')
])
)
Is this a fine approach? Unfortunately, while I have it functionally working with nested where statements inside of with clauses, when I try to get the types to be inferred all the way down I end up with:
error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.
My question is - has anyone tried full front to back end type inference? Or even just how to best handle findMany params via the request?
16 replies