I'm using Vue 3 with TypeScript and JSX (not Vue <template>s). When I use a <input type="range"> like this to edit a model:

export default defineComponent({

  setup(props, { emit }) {
    const state = ref(123)

    return () => {
      <input type="range" v-model="state">
    }
  });
}

I don't get a type error at compile time. When I run the code, editing the range input will change state from storing a number to storing a string value, violating the safety checks I'm meant to get from TypeScript and causing bugs elsewhere.

  1. How can I make this show a type error at compile-time?

  2. How can I fix this so only numbers are written to state?

I tried using v-model.number but this doesn't seem available in JSX?

My current workaround is to add

onInput={() => { state = parseFloat(String(state)); }

to do the conversion. This is error prone though, plus I'm not sure if watchers or anything might see the string version of the model before I convert it to a number.

Edit: If it makes a difference, I'm using default Vite settings to build this.

1

There are 1 best solutions below

0
On

Based on the jsx plugin plugin you could do something like :

<input v-model={[state, ['number']]} />