Reputation: 1815
What is the proper way to type HTML attributes in Vue 3, both when dealing with $attrs
in template and useAttr()
in script setup
?
In my use-case, we are specifying a name for Vee Validate's useField
method which can either use the HTML ID, if present, or a specified prop value.
<template>
<label for="$attrs.id">{{ label }}</label> // Type 'unknown' is not assignable to type 'string | undefied'.
<input type="checkbox" :id="$attrs.id" /> // Same error here
</template>
<script setup lang="ts">
import { useAttrs } from 'vue'
import { useField } from 'vee-validate'
const props = defineProps<{
fieldName: string,
rules: string
}>()
const attrs = useAttrs()
useField(attrs.id || props.fieldName, props.rules) // Argument of type 'unknown' is not assignable to parameter of type 'MaybeRefOrGetter<string>'
</script>
I know I could coerce to a string in the script tag or a computed, e.g. const idAttribute = ''+attrs.id
, but that feels wrong. I also could use a ref such as const idAttribute = ref(attrs.id as string)
but that still feels clunky.
Upvotes: 0
Views: 2310
Reputation: 14639
Every key-value on $attrs is typed as Record<string, unknown>
, so TypeScript will need your help understanding the actual type if you're using them in your code, either in the script or in the template which can be done like this:
<template>
<label :for="($attrs.id as string)">{{ label }}</label>
<input :id="($attrs.id as string)" type="checkbox" />
</template>
Upvotes: 1