Yup, I’ve taken to doing this exact same thing in TS/JS. That is, defining functions to take an options object instead of multiple parameters.
It’d be much nicer if TS/JS could support named parameter binding, like many other lanaguages, cause that’s what I do as a nearly universal rule, in every language that supports it.
No, having an IDE inject paramter names in the editor is not a solution. Not only does it always look like shit, because none of them have any concept of formatting for readability, it also means the code then becomes unreadable outside of an IDE (and user configuration) with that feature.
Agree with several people here that named parameters are a good solution, they add minimal overhead at the call site and function declaration and look very natural.
Another option for languages that want function arguments to have fixed size is bitmasks. I wonder if it could be a useful language feature to infer the flag names from the function declaration. Something like
def my_function(arg1, arg2, [FLAG1, FLAG2]) { if (FLAG1) { do thing } ... } my_function(val1, val2, FLAG1 | FLAG2)I use keyword arguments in Python to minimize this pain. Instead of
create_user("Bob", True, False)it’s
create_user(name="Bob", admin=True, send_email=False)JavaScript makes that more cumbersome with the object thing , but it’s better than nothing.
C# uses
CreateUser(name: "Bob", admin: true, sendEmail: false)This! There’s also a longstanding open issue on rust to allow a similar way to pass keyword/named arguments. IMO every modern language should have something like this. Makes all the difference when reading code.
Inlay hints from your editor are a good help, but this should be built into the language.
Rust doesn’t need this as much because it has enums so you can just do
create_user(user, Role::Admin, Notify::None).you can have a better data structure in any language, but rarely someone will bother doing that for booleans
Right cause the boolean isn’t a named type. If you have two possible states that can be represented with a boolean, or an enum of the two possible states which embeds more info into the callsite
zig uses anonymous structs for the same effect
doWork(.{ .flurbify = true, .flurbification_intensity = 1001, });Thank you for posting this comment. I came here to write the exact same thing and now I don’t have to!
👍
You could use jsdoc comments.
Good IDEs have multiple ways of showing you this info, and many languages have named parameters that fix this. Also, just putting a comment on them is not a crime, it just won’t update when you change the function but then your IDE can often only do so much at call sites, so you often need to update the calls (and the comments) manually. I’m sure LLM agents can change both as well.
Or, in JavaScript like these examples were, yeah, just pass in an object. Passing in an object should be standard in JS when you have more than like 2 params anyway because it solves several issues with parameter identification, optional parsms, method overloading, and so on. And JS passes everything by reference so you aren’t losing performance.
code should be readable without an Ide
Indeed. There will be lots of times when you’ll be reading code without a while IDE attached. When doing code reviews in the browser, when looking at patch files or git diffs in the command line, when browsing code files on some git host, or when you’ve gone to a confrence and you left your laptop in the hotel room because Steve from accounting assured you it would just be a meet-and-greet with clients, but then some production bug hit and every odd-numbered request is returning a 401 for some reason, so you need to borrow Steve’s laptop to fix this.
TypeScript doesn’t really save this
TypeScript tells me the values are booleans. That’s not really the problem.
The types are technically correct. I still have to remember what the arguments mean.
You could use branded/tagged types. Probably not useful in these narrow, one-off occurrences. But if you have a concept that applies across your whole domain, they can be useful.
branded booleans?
That’s why IntelliJ shows you, in these kinds of cases, the names of the parameters where the function is called…
There are also languages, like Scala and Swift, with named parameters, which also solve this problem.
IntelliJ doesn’t help when you’re doing a code review, or just reading through hundreds of lines of code, I don’t want to move my mouse or cursor over every line to see the parameter names.
I agree with you. However, I think you’ve misunderstood what inlay hints look like. Here’s an example.

By default inlay hints are enabled so you wouldn’t have to do that. But yeah it’s tied to using the editor which makes it a non solution
but isn’t that just using tooling to de-obfuscate code that should be clear to begin with?
passing structs, dicts, whatever keeps the code clear, expressive and extensible. if I can bake-in flexibility and clarity without being overly focused on performance, I am choosing the former every time.
You shouldn’t need tooling to fix an issue. Better for a design that does not require extra tooling.
If your language requires an IDE to show you WTF is going on in the code, it’s a bad language.
Given, there’s ways to write poor code in any language, but some are much, much worse than others. Java and JavaScript being the kings of that kind of thing.
Some day, AI assisted coding will become so intelligent that it will look at your average “enterprise” Java code and ask the user, “WTF were they even trying to do here?” Which is the only correct response a lot of the time.









