Any way to replace null by undefined?

Before using Drizzle, I was using the type mapper and the transform option of postgres.js in order to transform undefined to null. That way, any inserted undefined would be inserted as null in the database, and any null value in the database would be an undefined in JS. I'm looking for a way to do this with Drizzle. AFAIU as I'm still using the postgres.js connector, I can continue with these options, so the issue is to use undefined instead of null in the types. Similarly to changing a column type with .$type<T>(). Thanks!
29 Replies
francis
francis•10mo ago
I don't think you actually want to do this having {a: someValue, b: undefined} result in a different operation from {a: somevalue} will be incredibly hard to reason about and debug once you're sufficiently abstracted away from the operation it means you can't e.g. spread object values into an update call, then undefined out fields you don't want touched, you have to explicitly use the delete keyword
Luxaritas
Luxaritas•10mo ago
Yeah I'd be inclined to agree. null -> "there, but explicitly does not have a value" vs undefined -> "this property does not exist"
francis
francis•10mo ago
yeah, I've interacted with libraries that do dumb stuff like this where e.g. passing {option: undefined} is different from passing {}. As a user, please don't do this it is technically allowed to have the lack of a key do different things than the key be present and have the value undefined, but almost no developers will expect it, and almost no developers will check to see if you're doing something unusual until they get bitten by it
empereurdusel
empereurdusel•10mo ago
GitHub
eslint-plugin-unicorn/docs/rules/no-null.md at main · sindresorhus/...
More than 100 powerful ESLint rules. Contribute to sindresorhus/eslint-plugin-unicorn development by creating an account on GitHub.
francis
francis•10mo ago
strong disagree with that lint rule since you can't stop other libraries from returning and/or accepting null as a meaningful value separate from undefined just look at drizzle, for example, where {a: null} is different from {a: undefined} which is the same as {}
Angelelz
Angelelz•10mo ago
We f... up as a society by inventing null, now we need to embrace it lol
louneskmt
louneskmt•10mo ago
that would apply to bare javascript, but i think it's a bit different for ts. most of the time objects are typed so you can't access a non-existing property. we don't really need null in TS life is so much easier since i've dropped using null in my projects
Luxaritas
Luxaritas•10mo ago
What you're suggesting is that we actually don't need undefined. HOWEVER. What about the case like here where an object is being used as a map? How do you differentiate between "I don't want to set this property" (eg, using a default) vs "I want to set this property to null"?
louneskmt
louneskmt•10mo ago
well, that's a problem but solely due to the library
Luxaritas
Luxaritas•10mo ago
You could just rely on key presence, but it makes it more of a pain to conditionally pass
louneskmt
louneskmt•10mo ago
i don't really see where the pain is? ah, you mean for the map then use a Map?
Luxaritas
Luxaritas•10mo ago
...except maps don't have a limited set of keys Lets say I'm updating a table with values x, y, and z
{
x: foo ? bar : undefined,
y: foo ? bar : undefined,
z: foo ? bar : undefined
}
{
x: foo ? bar : undefined,
y: foo ? bar : undefined,
z: foo ? bar : undefined
}
vs
{
...(foo ? {x: bar} : undefined),
...(foo ? {y: bar} : undefined),
...(foo ? {z: bar} : undefined),
}
{
...(foo ? {x: bar} : undefined),
...(foo ? {y: bar} : undefined),
...(foo ? {z: bar} : undefined),
}
Admittedly it's not terrible But what if x y and z are conditionally provided to your function and you just want to pass them through? {x, y, z} and you're done vs
{
...(x ? {x} : undefined),
...(x ? {y} : undefined),
...(x ? {z} : undefined),
}
{
...(x ? {x} : undefined),
...(x ? {y} : undefined),
...(x ? {z} : undefined),
}
louneskmt
louneskmt•10mo ago
it's the same as doing directly this? {x, y, z}
Luxaritas
Luxaritas•10mo ago
No, it's not In the case of {x, y, z}, it will expand to {x: undefined, y: undefined, z: undefined}
louneskmt
louneskmt•10mo ago
yes
Luxaritas
Luxaritas•10mo ago
Being able to just do {x, y, z} is way simpler Than having to conditionally include keys everywhere
louneskmt
louneskmt•10mo ago
why is it a problem to have properties that are undefined? mmh i see
Luxaritas
Luxaritas•10mo ago
Because I need a way to distinguish between update this value by setting to null vs do not update this value
louneskmt
louneskmt•10mo ago
i understand
Luxaritas
Luxaritas•10mo ago
(Also remember that TS types work by satisfaction - a passed type can have an arbitrary number of additional keys even if you don't ask for them)
louneskmt
louneskmt•10mo ago
but tbh i've never been in a situation where this is a problem
Luxaritas
Luxaritas•10mo ago
An update method with an ORM is the exact place you have that problem 🙂
louneskmt
louneskmt•10mo ago
i don't use ORMs, that must be why haha
Luxaritas
Luxaritas•10mo ago
ORM or query builder or whatever
louneskmt
louneskmt•10mo ago
been trying drizzle but i always use raw sql
Luxaritas
Luxaritas•10mo ago
Without null --> null and undefined --> do nothing, you have to go through a bunch of extra work to conditionally include keys when eg passing through from an API request to a model
Angelelz
Angelelz•10mo ago
You can't get rid of nulls, all database systems have them
Luxaritas
Luxaritas•10mo ago
That's why I'm saying it would make more sense to get rid of undefined than null - semantically, the thing you don't like is undefined 🙂 Admittedly, other languages don't do this, and they do have to take one of the other approaches But it's more useful in JS where objects are so loosely defined
francis
francis•10mo ago
I think it's actually quite good that you can set a value which is identical (in theory) to the absense of a key. mean you can do things like spread options into an object, and options that are undefined don't get set, rather than having to set the presense of each key individually as shown above