Modifier optional positional argument interferes with named argument #627
-
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Optional positional arguments are not supported, because we model the combination of positional and named arguments as a list of arguments with the positional arguments first and then a named argument object at the end of the list. Given that, the actual type your signature represents is something more like this: function translatedFoo(
b: boolean,
s?: string,
options: { debounce?: number }
): void; That signature is not legal TypeScript, though, as you can see in this playground. You end up with a different error message from Glint than the one in the playground because of the specific details of how we do the transformation and then supply the arguments to it in the template, but the basic issue is the same. The key here is to realize that we have to do shenanigans because the distinction between positional and named arguments is totally foreign to JavaScript and therefore TypeScript. The concept (like a lot of things in Handlebars!) comes from Ruby in terms of its actual history; and while Ruby, Python, and other languages have this distinction, JavaScript does not. As a result, we do our very best, but there are just spots where it is not possible. As a good heuristic, then, try to think about how you would write a JS function that has the properties you want, and build your signatures that way! Knowing the specifics of how we transform it may help a little, in that you can see why you get the specific error that you get here—but more generally just recognize that you should aim for definitions that are JS-friendly rather than doing Ruby- or Python-like mixes of named and positional arguments with optional positionals! Note In case anyone wonders: the specific details of our representation here are mostly incidental: any representation would have some set of problems in this space. Indeed, we tried other ways of modeling this earlier on in the history of Glint, including using tuple types for positional arguments, or putting the named argument block first instead of last. All of those had even worse problems than this. (For a couple particular examples see the sections on higher-order inference and pre-binding arguments in the deep dive we put up on YouTube about the component transform.) |
Beta Was this translation helpful? Give feedback.
Optional positional arguments are not supported, because we model the combination of positional and named arguments as a list of arguments with the positional arguments first and then a named argument object at the end of the list. Given that, the actual type your signature represents is something more like this:
That signature is not legal TypeScript, though, as you can see in this playground. You end up with a different error message from Glint than the one in the playground because of the specific details of how we do the transformation and then supply the arguments to it in the template, but …