Subquery from a function
I want to reuse a sub-query that refers to one of the fields in the root query's result.
I tried doing this:
However, I get a bunch o' errors I don't quite understand:
If I pick that exact expression and paste it directly in the
.select(eb => [/* here */])
of the parent query, then there are no errors.
I assume that it's trying to tell me that check_is_friend
might collide with the parent's scope or something like that? Am I doing something silly, is there a better way to do this?Solution:Jump to solution
Don't pass in the expression builder. Its type easily becomes incompatible in other contexts.
Don't use an explicit result type. The result type here is NOT
boolean
. It's { is_friend: boolean }
. Yes, you can use that as a scalar in SQL and Kysely does handle that correctly. But don't explicitly set the wrong type.
You always need to provide a name for selections using the as
method. The name is dialect-specific if you leave it out. Since kysely types don't know which dialect you're using, providing a name for that column automatically is impossible....6 Replies
Solution
Don't pass in the expression builder. Its type easily becomes incompatible in other contexts.
Don't use an explicit result type. The result type here is NOT
boolean
. It's { is_friend: boolean }
. Yes, you can use that as a scalar in SQL and Kysely does handle that correctly. But don't explicitly set the wrong type.
You always need to provide a name for selections using the as
method. The name is dialect-specific if you leave it out. Since kysely types don't know which dialect you're using, providing a name for that column automatically is impossible.
and then use it like this
If I pick that exact expression and paste it directly in the .select(eb => [/* here */]) of the parent query, then there are no errors.This is definitely not true. Your code had a bunch of errors. If that worked, you've disabled typescript type-checks completely. Yes, the compiled javascript probably works by accident. But you've compiled it without any type-checks if it does.
How is that playground you posted related?
huh this loads something to do with publicKey or whatever which is the code from another question I had clicked earlier, idk what's up with that. must have not clicked to regenerate the hash or something, thoug i didnt see a buton for that. anyways
thank you, that makes more sense yeah. what would be the return type I should use here?
AliasableExpression<{ is_friend: SqlBool }>
is not enough for kysely to resolve it as a single boolean.
on the call site:
Then when accessing row.is_friend
, I get back an object:
Deno: Argument of type { is_friend: SqlBool; }
is not assignable to parameter of type boolean
(I can't use an implicit return type since this is actually an abstract method)Just leave out the return type. The implicit type will get resolved correctly
But if you really want to have an explicit return type that works, It's something like
The next version will have a
$asScalar()
type helper for these cases. Then you could use AliasableExpression<boolean>
as the result type and chain $asScalar()
at the end of the query.
Or you can use .$castTo<boolean>()
at the end of the query for now and then an explicit AliasableExpression<boolean>
as the return type.
But that's not type-safeFair, yeah i need an explicit type here since it's an implementation of an abstract method, and the abstract method requires an explicit return type.
$asScalar
would be perfect here, since the other implementation of this method would be just a simple eb.lit(false)
nice, I'll use a the cast for now with a comment to upgrade when it comes out
thank you for taking your time to explain things so clearly