Airplane
Airplane3y ago

Schema for Record types

when defining a schema, for s.object() is there a way to restrict the types of values but allow any arbitrary key? e.g. the equivalent of this in typescript:
interface MyInterface {
[key: string]: number;
}
interface MyInterface {
[key: string]: number;
}
4 Replies
ballingt
ballingt3y ago
Currently you need to use a Map for that with a schema. I can see where you're coming from, in JS the record type is idiomatic. The thinking here is that for supporting other languages down the line, s.object is describing a specific shape while map: s.map(s.string(), s.number()) is for describing a record like this. @Airplane I'd love to hear what you think of trying this, I'd probably call Object.fromEntries(myMap) inside a Convex query function to return an object instead.
Airplane
AirplaneOP3y ago
ah I see, that makes sense thanks! Would it also be possible to do
s.union(s.object({
myKey: s.number()
}), s.map(s.string(), s.number())
s.union(s.object({
myKey: s.number()
}), s.map(s.string(), s.number())
to create a combination of required properties but also allow for extra ones? At this point my understanding is that schemas are a typescript-only feature, so would doing something like this actually compute the corresponding types?
ian
ian3y ago
I don't believe this will give you required fields, as the union would allow either {myKey: 3} or {otherKey: 2} or both. you could nest the map inside of an object though: s.object({myKey: s.number(), otherKeys: s.map(s.string(), s.number())})
alexcole
alexcole3y ago
Oops, I was late to see this, but @Airplane thanks for the feedback! In TypeScript terms, what you are describing is an index signature. Our schemas don't support them right now, but we could add support in the future. And yeah doing a union of s.map and s.object won't work either because Convex will expect you to either have an object ({}) or a map (new Map).

Did you find this page helpful?