script block next to script setup is in TSX mode by default
Version
3.1.4
Reproduction link
Steps to reproduce
Use script setup with lang="ts"
, add a regular <script lang="ts">
block next to it, containing a cast.
What is expected?
Compiles fine.
What is actually happening?
Compilation error, seems like the script block is handled as TSX by default.
Regular TS and TSX are not compatible, there are ambiguities with casts and (sometimes) generic syntax.
Users should opt into TSX with lang="tsx"
.
Does this happen in other cases than the old version of casting? You should use as any
instead as it was introduced in TS to avoid this kind of issues. (https://github.com/vuejs/vue-next/issues/3598)
I wasn't aware this syntax was old or not recommended. The official docs say:
You can also use the angle-bracket syntax (except if the code is in a .tsx file), which is equivalent
And in the as section:
Since the above syntax cannot be used in .tsx files, an alternate type assertion operator should be used: as. The example can easily be rewritten with the as operator.
Doesn't sound very deprecated to me.
To answer your quetion: yes there are other syntactic ambiguities, related to generics. See for example: https://stackoverflow.com/questions/32696475/typescript-tsx-and-generic-parameters
I think there's a reason why TS has a flag to opt into the TSX syntax, and it would be good if Vue followed suit. It's not nice to have to come up with work-arounds to perfectly valid code.
Thanks for the links! So the as
cast can always be used while the other one cannot. That is enough of a reason to not use the half working syntax. After all, the as
cast was introduced because of the incompatibility of the old cast syntax with jsx.
If right now tsx works in lang=ts
, introducing the change you are suggesting is a breaking change.
https://stackoverflow.com/questions/32696475/typescript-tsx-and-generic-parameters
That one works in the SFC playground.
I agree using as
instead of cast is not a big deal.
Generics problems can be complex to work-around as demonstrated in the SO discussion.
That one works in the SFC playground.
For the anecdote, generics problems happen.
I had opened an issue in eslint-vue plugin exactly for that, some of my generic code was not parsing correctly.
(and eslint-vue was changed to take tsx
as an option).
If right now tsx works in lang=ts, introducing the change you are suggesting is a breaking change.
Is it really?
I think regular <script>
components are not affected by that, as the code is just passed through.
In fact, when I opened the eslint issue, I had no compilation problem, just linting.
So if this is specific to script setup
compilation, then it's still marked as experimental and this is the last moment to fix it!
So if this is specific to script setup compilation, then it's still marked as experimental and this is the last moment to fix it!
That's true! It would be acceptable to change the behavior right now and I doubt it will affect a lot of people.
I haven't tried the different combinations but keeping the behavior coherent between different usages of setup
to either handle TSX/JSX or not is more important IMO because it's easier to debug an invalid <any>
cast in TSX (the error is very easy to lookup on the internet) than the same script behaving differently because it is next to a setup script and need a change of the lang to tsx
.