phatskat
phatskat

Reputation: 1815

Typing HTML Attributes in Vue 3 with TypeScript

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>

What I've Tried

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

Answers (1)

yoduh
yoduh

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

Related Questions