Is there a way to get around the Id<"tablename">
Ive been looking in the docs trying to figure this out so that using convex is a lil more type friendly.
Situation:
Ideally want to keep using the Id<"tablename"> when defining my tables in convex's schema.
BUT
throughout the rest of my app, i dont want to be constantly having to " as Id<"tablename"> " for all my relational fields
I've tried the " Doc<"tablename">
but that still returns fields with the Id<"tablename"> (see screenshot) Anyone got a solution for this?
but that still returns fields with the Id<"tablename"> (see screenshot) Anyone got a solution for this?
12 Replies
Ok my buddy came up with something like this
can you show more of the code causing the error? normally you want your code to keep the typesafety end-to-end; you shouldn't need to cast often
this nightmare of a thing
huh. Have you considered using
v.union(v.literal(""), v.id("tcgs"))
in your schema, if that's supposed to be a valid document?but then that would allow it to be "nullable"
It looks to me like it is nullable. The code is saying that
tcgId: ""
can be used to construct a valid Doc<"tournaments">
your workaround looks fine to me, btw 🙂
you could also use const fakeId = "" as Id<any>
and use that everywhereThat's just initializing the state (svelte app).
I assume if we try to save that empty string to convex that it would then throw an error because "" is not a valid id for the TCGs table
What is the state used for? I still don't understand why having an invalid
Doc<"tournaments">
in svelte state would be useful. Would it be possible to do let tournamentState = $state<Doc<"tournaments">[]>([]);
instead?that screenshot i sent ya is using the convex's Doc<>.
And so my typescript throws a nightmare of type insecurities, because im initializing my state with an empty string (because the user has not selected the typeId yet).
But using my work around causes no issues.
I would recommend adding this workaround to the convex docs for otherss
I still don't understand how you're using this state, and why it's okay to initialize the values with the wrong types. It's like doing
let mystring = $state<string>(0.0)
; it's not going to work without castingbecause Id<"tablename"> is fundamentally just a string.
And an
<input type="text">
is not Id<"tablename"> rather its a string.
Correct me if im wrong, but
Id<"tablename"> only has importance at the time of writing to the database to enforce relationality.
On the client side having to cast it to Id<"tablename"> every time its being passed doesn't actually enforce relationality. So its pointless to not just treat it as a string type.no,
Id<"tablename">
isn't just a string. it's a subtype of strings that has a minimum and maximum length, only allows certain characters, and has some other restrictions. So the empty string is never a valid Id<"tablename">
, just like 1.5 isn't a valid BigInt
.
Furthermore, there actually is not runtime check that enforces relationality. You can hypothetically construct an Id<"tablename">
that has never existed before, and it will pass all arg and schema validation.