Looking at the AST [0], this doesn't seem to be the case. Since Typescript already supports decorators in other contexts, it successfully parses everything and identifies the decorator to boot. Since you're working in a preprocessor context anyway, there's a number of options to make all of this work well together.
Well yes, that's the sane way anyone would reach for first, but that's clearly not new-age enough by Vercel's standards, so here we are. Similar to the other magic string interactions, all of this is a roundabout way of introducing platform lock-in.
The problem with higher-order functions is that you can't guarantee that your static analysis is correct, and you end up with functions that look like functions but don't behave like functions.
It's similar to the problem that `require` had in browsers, and the reason that the `import` syntax was chosen instead. In NodeJS. `require` is just a normal function, so I can do anything with it that I could do with a normal function, like reassigning it or wrapping it or overwriting it or whatever. But in browsers (and in bundlers), all imports need to be statically known before executing the program, so we need to search for all calls to `require` statically. This doesn't work in JavaScript - there are just too many ways to dynamically call a function with arguments that are unknown at runtime or in such a way that the calling code is obscured.
That's why the `import` syntax was introduced as an alternative to `require` that had rules that made it statically analysable.
You'd end up with a similar situation here. You want to know statically which functions are being decorated, but JavaScript is a deeply dynamic language. So either you end up having a magic macro-like function that can only be called in certain places and gets transpiled out of the code so it doesn't appear at runtime, or you have a real function but you recognise that you won't be able to statically find all uses of that function and will need to set down certain rules about what uses can do with that function.
Either way, you're going to be doing some magic metaprogramming that the developer needs to be aware of. The benefit of the "use X" syntax is that it looks more magical, and therefore better indicates to the reader that magic is happening in this place. Although I agree that it's not my personal preference.
But you can see there that it flags it as an error. The parser is lenient, sure, and tries to parse the rest of the file despite the error, but it's still not valid syntax, so you'd need to update all your other tools (LSP, formatter, linter, etc) to understand the new syntax.
Looking at the AST [0], this doesn't seem to be the case. Since Typescript already supports decorators in other contexts, it successfully parses everything and identifies the decorator to boot. Since you're working in a preprocessor context anyway, there's a number of options to make all of this work well together.
[0] https://ts-ast-viewer.com/#code/GYVwdgxgLglg9mABMOcAUBKRBvAU...
Instead of decorators, it could be just a higher-order function. Which could handle it easily and in any scenario that interchanges between TS/JS.
Well yes, that's the sane way anyone would reach for first, but that's clearly not new-age enough by Vercel's standards, so here we are. Similar to the other magic string interactions, all of this is a roundabout way of introducing platform lock-in.
The problem with higher-order functions is that you can't guarantee that your static analysis is correct, and you end up with functions that look like functions but don't behave like functions.
It's similar to the problem that `require` had in browsers, and the reason that the `import` syntax was chosen instead. In NodeJS. `require` is just a normal function, so I can do anything with it that I could do with a normal function, like reassigning it or wrapping it or overwriting it or whatever. But in browsers (and in bundlers), all imports need to be statically known before executing the program, so we need to search for all calls to `require` statically. This doesn't work in JavaScript - there are just too many ways to dynamically call a function with arguments that are unknown at runtime or in such a way that the calling code is obscured.
That's why the `import` syntax was introduced as an alternative to `require` that had rules that made it statically analysable.
You'd end up with a similar situation here. You want to know statically which functions are being decorated, but JavaScript is a deeply dynamic language. So either you end up having a magic macro-like function that can only be called in certain places and gets transpiled out of the code so it doesn't appear at runtime, or you have a real function but you recognise that you won't be able to statically find all uses of that function and will need to set down certain rules about what uses can do with that function.
Either way, you're going to be doing some magic metaprogramming that the developer needs to be aware of. The benefit of the "use X" syntax is that it looks more magical, and therefore better indicates to the reader that magic is happening in this place. Although I agree that it's not my personal preference.
But you can see there that it flags it as an error. The parser is lenient, sure, and tries to parse the rest of the file despite the error, but it's still not valid syntax, so you'd need to update all your other tools (LSP, formatter, linter, etc) to understand the new syntax.