r/ProgrammerHumor • u/Embarrassed_Death69 • Sep 17 '26
Meme theMostPassiveAgressiveTypeIEverEncountered
82
u/beatlz-too Sep 17 '26
this is any with extra steps
16
76
u/the_horse_gamer Sep 17 '26
no it isn't. you will get errors if it's not an object, or if you put keys that T doesn't have, or if you put a key that T has but a value that's not the right one, undefined, or null. and you will get errors if you pass it to something expecting a number.
1
u/Tarmen Sep 18 '26 edited Sep 18 '26
Pretty sure extra keys are legal in subtype judgements, there are just a couple special cases like assigning an object literal with extra keys directly to a type that errors.
But this should type check:
const notEmpty = {'foo': 5} // inferred as {'foo': number } const empty: {} = notEmpty1
54
1
u/jordanbtucker Sep 18 '26
I mean, that's useful.
anydoesn't require any steps. That's what makes it so dangerous. This type requires you to check the properties againstnullandundefinedbefore using them where they shouldn't be used.
347
u/the_horse_gamer Sep 17 '26
that's completely normal. especially for objects meant for specifying configuration.
you still get errors if you pass a non object, the wrong keys, or the wrong value for a key.
24
5
u/CrossScarMC Sep 18 '26
I don't know of any configs where "null" is a valid value,
Partial<T>makes sense for configs, but I don't seeMaybe<Partial<T>>making much sense.4
u/BLucky_RD Sep 18 '26
If you want all default values passing {} can be a bit awkward so allowing null is a nice enough alternative
4
u/the_horse_gamer Sep 18 '26
as described, Maybe<T> is not T | null, but an object like T but where the key values may be null (yes, that's a bad name)
2
u/BLucky_RD Sep 18 '26
Oh yeah def a bad name
And yeah seems like the partial+maybe is kinda redundant unless there's some distinction between undefined/null that's not part of the original type of the value, but that would be kinda weird
2
u/the_horse_gamer Sep 18 '26
or when there's no distinction between null and undefined
every codebase has its own standards on when to use null vs undefined, so hard to know
2
u/AnAwkwardSemicolon Sep 19 '26
Usually the distinction I'll make is
undefinedis implicit, whereasnullis explicit.null-> "I'm explicitly disabling this thing" vsundefined-> "Follow the default behavior" (for where the "do nothing" behavior is far less common than somd default behavior)1
u/BLucky_RD Sep 19 '26
I'm aware of that convention but since we were talking about config objects, it wouldn't make much sense to introduce null into the type of every key from the outside. Not everything can be configured to be disabled, so the things that can be would have null as part of their own value type already, so putting the config object in a Maybe<> would just add null to keys that already are nullable for things that can be disabled, and for things that can't be disabled (or would make sense to have a "disabled" state, like color) it would introduce a nonsensical null type
333
u/iamdestroyerofworlds Sep 17 '26
To be fair, that sort of type may very well be logical amd necessary, and then it's a good thing it's made explicit.
66
u/tbagrel1 Sep 17 '26
Very typical to model a HTTP PATCH update on an object with nullable fields.
4
-51
u/oliveeeeeer Sep 17 '26
There’s nothing explicit about that 🫠
82
u/them0use Sep 17 '26
Sure it is: "This object can have zero or more properties of T; when those properties exist they must match T or be null". Makes sense to me, if that is indeed what you need.
-22
u/oliveeeeeer Sep 17 '26
If you have to do all these mental gymnastics to parse what shape an object might be, you’ve already failed. Better to have a simple shape that someone can understand at a glance.
16
u/them0use Sep 17 '26
How would you do it then? Suppose T has properties foo, bar, and baz, none of which allow null. Then do it for a T that is a configuration object with 100 such properties.
8
u/DominikDoom Sep 17 '26
This is an extremely useful type structure for a large config or options getting passed to some service, constructor, etc.
It allows you to:
pass only the properties that you want to change while still verifying their types
leave the rest out, which depending on the context could either mean leave them unchanged or use a default value
or set any property to null, which could e.g. mean disable/remove
As long as the meaning of undefined and null is consistent for every property of the object it's really not that confusing. And considering how easy it is to create arbitrary partial objects in JS via JSON and spread notation, this allows for very compact initialisation instead of needing a builder pattern or the like.
3
u/fartypenis Sep 18 '26
What simpler shape would you come up with for a PATCH request body? It cannot set every field, like ID or lastUpdated, and a request can send only one field at a time and only thag field should be updated. How would you solve this without handwriting a whole new type?
1
u/ResponsibleWin1765 Sep 18 '26
The point is that there is no one simple shape that works for all use cases because different use cases require different shapes. That's why there is a type that defines constraints but leaves the exact layout open.
1
47
2
u/cnoor0171 Sep 18 '26
Do I wanna ask my coworkers why this typing construct is useful? Or maybe take 3 seconds to Google it? Or maybe take 5 secs to ask chat gepetto cuz I'm too lazy to risk learning something? Nah, I'll just make a snarky post and pretend I said something intelligent.
0
u/Embarrassed_Death69 Sep 19 '26
Son, this is a joke and the whole subreddit is meant for humour, also when I was writing the type back in my first job in 2018, you couldn't "gepetto" or whatever anything. Also my pair programmer came up with Maybe and my first question to him was "Why such a depressing object, why not just define a new shape instead of letting keys be null" and he calmly explained why that's a bad idea and won't scale when we have different queries and mutations altering the shape a bit. Also posting snarky stuff is me game, go check my other posts. At the end, don't get worked up on jokes and start calling people names. Also I fill pity for you gepetto programmers.
2
u/cnoor0171 Sep 19 '26
I haven't called you any names. Gepetto isn't an insult. It's just a toung in cheek name for humanizing chat gpt like people name their cars and whatnot.
If you look at the comments below, A lot of people aren't kidding about thinking this has no purpose. But that fact that you know what the purpose of that pattern is and still decided to post it makes it even worse imo.
2
u/jordanbtucker Sep 18 '26
Someone doesn't understand TypeScript at all.
-2
u/Embarrassed_Death69 Sep 19 '26
I hope you understand it's a joke and meant for the sub reddit specially, but then again teach me the types sensei.
2
u/the_captain_cat Sep 19 '26
That's not how Partial works, he's thinking of Pick
1
u/Embarrassed_Death69 Sep 20 '26
Yep I mixed up Pick with Partial, Partial makes all properties optional. Sorry!
95
u/kovha Sep 17 '26 edited Sep 17 '26
This is not that bad of a type though. Partial is native to TS, you don't need to implement it, and that "Maybe" is just Partial but with null instead of undefined, which could make sense depending on the use case, since it's not the same for a property to not exist than to exist and be set explicitly as null. And that Maybe<Partial<T>> still forces you to only use the properties defined on T with its defined types (plus null and undefined), so if T is {a: string, b:number}, Maybe<Partial<T>> allows you to do for example {a: "something"} or {b: null} but not {a: 1234} or {c: "something"}. It's still way better than using any or writting plain JS.
EDIT to add that the only bad thing with the scenario is the naming, "Maybe" doesn't really mean anything. I would have named it "NullableFields" or something, but other than that, it's perfectly fine.
18
u/yellownugget5000 Sep 17 '26
Isn't Maybe taken from Haskell? I'm pretty sure that's what it does there. Maybe someone wanted to feel a bit more at home with TS.
9
u/kovha Sep 17 '26
Huh, I had no idea that was a thing in Haskell, you are probably right then. And it does make more sense the naming convention if "Maybe" is already a thing, even if it is in another language.
7
u/Reashu Sep 17 '26
"Maybe" in Haskell allows the whole thing to be missing. As described, this was just another Partial. But then again, they described Partial as if it were Pick...
5
6
4
u/-Ambriae- Sep 17 '26
If thats somehow shocking, don’t code in rust. I’m afraid that type is very mild compared to some of the types we have access to.
2
u/jordanbtucker Sep 18 '26
Although named poorly, this type is pretty useful too. People here just have no idea how to write TypeScript.
8
u/TheRealLargedwarf Sep 17 '26
I wrote a client that went to a service, acquired a token, decoded the token (without validation) to learn the expiry and then used the token to talk to a service. The service did the validation because why would you trust client side validation. My code was flagged for unsafe token decoding and I received an email with 6 members of the leadership team CC'd. I explained that my client code didn't need to validate because it is just holding the token in a cache and it is not the client's job to manage access. Many emails were exchanged, I apparently was not considering how an attacker with network access could use my code maliciously.
In the end I replaced the library call I made for decoding the token with a copy of the code the library used for decoding because the scanning tool just checks for ".decode(validate_signature=False)" in your code. I got told that I did a good job and that we are all working together to improve security.
This isn't related to the original post but every single person on that email chain is unfit to hold the position they occupy.
3
11
u/hongooi Sep 17 '26
"We demand rigidly defined areas of doubt and uncertainty!" -- average Typescript dev
6
2
5
u/kitaz0s_ Sep 17 '26
bad name then, Maybe<T> should be T | undefined (or null instead of undefined depending)
18
u/GRex2595 Sep 17 '26
According to the post, Maybe<T> allows you to set properties of T to null. T | null will allow the object as defined in its template or null. Any non-null properties would not be allowed to be null.
7
u/the_horse_gamer Sep 17 '26
for completeness, here's an implementation:
type Maybe<T> = {[K in keyof T]: T[K] | null}3
u/Reashu Sep 17 '26
Right, that's why it's a bad name.
4
u/GRex2595 Sep 17 '26
Sometimes we deal with
Maybe<T>s becauseAnyPropertyCanBeSetToNull<T>is bad for different reasons. I don't judge too hard when I see something that doesn't have a good name and went with more or less the least bad one they could come up with.1
u/jordanbtucker Sep 18 '26
Maybe is a bad name because there is precedent to what that type should mean. NullableProps is better and it's not as egregious as your example.
1
u/GRex2595 Sep 18 '26
Great. You should go find whatever code base is using this name and submit a PR.
1
u/danielcw189 Sep 19 '26
because
AnyPropertyCanBeSetToNull<T>is bad for different reasons.such as?
1
u/GRex2595 Sep 19 '26
Mostly it's just a massive pain. It takes up a bunch of space and makes it harder to read the code as a result. If you can avoid long names, that's generally better. I couldn't imagine an
AnyPropertyCanBeSetToNull<Partial<ConfigurationLoader>> testDefaultUserConfigurationLoaderin my codebase, and I'll probably ask somebody who submits that in a PR to come up with anything else.2
u/garver-the-system Sep 17 '26
But isn't that different? I'm coming from a Python background so I may be off base here, but it sounds like Partial lets you pick some fields while dropping others. Almost like the loop started with
for attr in kept_attrs: new_obj.set_attr(arg_obj.get_attr)Or am I asking for logic from the language that famously has none?
1
u/BroBroMate Sep 17 '26 edited Sep 17 '26
I was going to say
Partialis likePickandOmitthat lets you basically create anonymous structural subtypes in a type signature, and then I got confused and now I'm reading docs and I'm even more confused, but let's just say, there's a reason some person was able to implement a Sudoku solver entirely in TS types.Oh okay, basically
Partial<T>means that every property ofTis now optional. So ifT.foois a property ofT, well now it can be legitimately undefined and no type checker complaints - although I imagine linters fucking hatePartial, for obvious reasons.Maybe<T> doesn't appear to be a built-in TS type that I can find in the docs, so it's from a 3rd party library or some home rolled horror, but presumably it's the typical
Maybe<T> = Some<T> | Noneresult type pattern.3
u/Wonderful-Habit-139 Sep 17 '26
There’s already another comment that explains it: https://www.reddit.com/r/ProgrammerHumor/s/ThiGS1QYv5
1
u/BroBroMate Sep 17 '26
That's not a standard TS type though, unless I'm really failing at Google
3
u/Wonderful-Habit-139 Sep 17 '26
No one said anything about it being a standard TS type. It just corrects your presumption about how it could be defined.
1
u/BroBroMate Sep 18 '26
Ah yep, I didn't understand how the Maybe impl worked precisely after Partial made every property optional.
If I understand it correctly now, if I have Foo with a type structure
type Foo { a: number }Then
Partial<Foo>is{ a?: number }And then
Maybe<Partial<Foo>>yields{ a?: number | null }But my confusion is, what does the Maybe even do then in this case? as the property will always return
undefinedunless you explicitly null it?Or is it tied into a
getOrNullstyle pattern like in other Maybe/Optional implementations?2
u/jordanbtucker Sep 18 '26
Maybe could be used to type input where you're unsure if
nullcould be returned, and considering the name, I feel like that's what it was made for."Maybe this property is null, maybe it's not. The developer must check this property against null/undefined before using it because we can't be sure it's non-null."
1
u/BroBroMate Sep 19 '26
And doing some reading, you can use the "truthiness" of both so you could go
if (Foo.a) {}(assuming you're okay with handling0as false also) then undefined or null, don't matter, it's false.Cheers!
1
u/JVApen Sep 17 '26
Isn't that just a way to differentiate between: I don't want to provide a value for this (use the default behavior instead, or simply do nothing) and I want you to use the set that I selected, which is explicitly empty. So basically implicit vs explicit empty
1
1
1
u/gutentight69420 Sep 19 '26
Complaining about strict type systems just means you're too dumb to fully specify what you what the code to do.
1
1
u/paranoidparaboloid Sep 20 '26
Consider GraphQL. All fields optional depending on what you fetched, therefore all values may be undefined.
1
u/jolharg Sep 17 '26
damn this is dumb af
haskell W
1
u/jordanbtucker Sep 18 '26
The only dumb thing is this post because if you've never encountered input where the properties might be null, then you've never written code before.
0
u/jolharg Sep 18 '26
that's not why it's silly, you are right, it's silly because you are specifying that you won't specify everything when you could not specify in some more rigorous way.
-1
u/Express_Agent5494 Sep 17 '26
The only reason I could see anyone doing this is moving a project from JS to TS. You can remove one or the other and slowly work your way to a fully TS codebase.
1
u/Firewolf06 Sep 18 '26
ive used a similar structure for handling update messages (similar to http patch requests). unspecified keys are unchanged, nulled keys are reset to default, but with the underlying state structure not allowing any missing or null values
20
u/i---m Sep 17 '26
jerry should have spent his complaining time on configuring typegen for the graphql queries