v-on/@ syntax incompatibility with type narrowing #732
Phlogistique
started this conversation in
General
Replies: 2 comments 3 replies
-
It would be nice to have this. I would add that the best workaround is to use the <div v-if="currentItem">
<SliderInpput @change="(newSize) => updateItemSize(currentItem!, newSize)"/>
<!-- Argument of type 'number | null' is not assignable to parameter of type 'number'. -->
</div> |
Beta Was this translation helpful? Give feedback.
1 reply
-
IMHO this is not a Vue-specific issue but rather a TypeScript problem. Consider this code let maybeNumber: number | null = null
declare function on(f: () => void): void
if (maybeNumber) {
on(() => {
maybeNumber.toExponential() // error here
})
} TypeScript will report |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
There is an ergonomic issue when combining TypeScript type narrowing with Vue's v-on event handlers in templates. When using v-if to narrow a nullable value, there is no way to use the variable with its narrowed down type inside an event handler, if you also want to use the other arguments passed to
emit
by the child component.Motivating example: I have an element that displays a list of items, and when I select an item, a slider to change an item's property:
This happens because there is no way to tell TypeScript that the function will not be called outside the type-narrowed scope.
Standard workarounds that feel wrong
We can force it to work with non-null assertions or runtime checks:
Where v-on throws a wrench in the works
A somewhat natural solution would be to capture the narrowed type in a constant; but that does not work as the Vue compiler syntactically detects a statement, and never calls the returned function.
Trying to use partial application yields the same result:
Alternative workarounds
change
event my child component takes anonChange
callback as a prop, you can successfully pull the "partial" trick above.:key
Or with a helper:
What I would like
I can imagine a world where, if you pass to v-on an expression that resolves to a function, it would get called by Vue when the event is received. That would make the
partial
trick above work.Another solution would be for Vue to put some magic
$args
variable in scope in v-on, that contains the arguments to the emitted event.Beta Was this translation helpful? Give feedback.
All reactions