All skills
hyf0 avatar

/vue-debug-guides

@a5fc891 official
by hyf0hyf0/vue-skills2.9k stars
167

Vue 3 debugging and error handling for runtime errors, warnings, async failures, and SSR/hydration issues. Use when diagnosing or fixing Vue issues.

Use this Skill: https://skilld.dev/gh/hyf0/vue-skills/vue-debug-guides

This session only. Nothing lands on disk.

referencets-template-type-casting.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Use Type Casting in Templates for Union Types

Impact: MEDIUM - When using lang="ts" in Vue Single File Components, template expressions get strict type checking. If a variable has a union type, you may need inline type casting to access type-specific methods or properties.

Task Checklist

  • Use (value as Type) syntax for type casting in templates
  • Consider narrowing types in script before using in template
  • Remember template type checking requires lang="ts" attribute
  • For Vue CLI/webpack: ensure vue-loader >= 16.8.0

The Problem

When a variable has a union type, TypeScript cannot know which specific type it is at template compile time:

Template with type error:

<script setup lang="ts">
// Union type: could be string OR number
let x: string | number = 1
</script>

<template>
  <!-- ERROR: Property 'toFixed' does not exist on type 'string | number' -->
  {{ x.toFixed(2) }}
</template>

TypeScript correctly identifies that toFixed() only exists on number, not string.

Solution 1: Inline Type Casting

Use (value as Type) syntax directly in the template:

<script setup lang="ts">
let x: string | number = 1
</script>

<template>
  <!-- CORRECT: Cast to number to access toFixed -->
  {{ (x as number).toFixed(2) }}
</template>

Solution 2: Computed Property (Preferred)

Create a computed property that narrows or transforms the type:

<script setup lang="ts">
import { ref, computed } from 'vue'

const value = ref<string | number>(1)

const formattedValue = computed(() => {
  if (typeof value.value === 'number') {
    return value.value.toFixed(2)
  }
  return value.value
})
</script>

<template>
  <!-- Clean template, type-safe logic in script -->
  {{ formattedValue }}
</template>

Solution 3: Type Guard Function

Define a type guard and use it in the template:

<script setup lang="ts">
import { ref } from 'vue'

const data = ref<string | number | null>(null)

function isNumber(val: unknown): val is number {
  return typeof val === 'number'
}

function formatNumber(val: number): string {
  return val.toFixed(2)
}
</script>

<template>
  <div v-if="isNumber(data)">
    {{ formatNumber(data) }}
  </div>
  <div v-else-if="data !== null">
    {{ data }}
  </div>
</template>

Common Use Cases

API Response Data

<script setup lang="ts">
interface ApiResponse {
  status: 'success' | 'error'
  data?: UserData
  error?: string
}

const response = ref<ApiResponse | null>(null)
</script>

<template>
  <div v-if="response?.status === 'success'">
    <!-- Cast to access data safely -->
    {{ (response as { data: UserData }).data.name }}
  </div>
</template>

Better approach with computed:

<script setup lang="ts">
const userData = computed(() => {
  if (response.value?.status === 'success') {
    return response.value.data
  }
  return null
})
</script>

<template>
  <div v-if="userData">
    {{ userData.name }}
  </div>
</template>

Event Handlers with Event Types

<script setup lang="ts">
function handleInput(event: Event) {
  // Cast to HTMLInputElement to access 'value'
  const value = (event.target as HTMLInputElement).value
  console.log(value)
}
</script>

<template>
  <input @input="handleInput" />
</template>

Array Item Access

<script setup lang="ts">
const items = ref<(string | number)[]>([1, 'two', 3])
</script>

<template>
  <ul>
    <li v-for="item in items" :key="item">
      <!-- Cast when you know the type -->
      <span v-if="typeof item === 'number'">
        Number: {{ (item as number).toFixed(1) }}
      </span>
      <span v-else>
        String: {{ (item as string).toUpperCase() }}
      </span>
    </li>
  </ul>
</template>

When Type Casting is Needed

Scenario Solution
Union types Cast to specific type
Nullable types Use optional chaining or cast after null check
Event targets Cast event.target to specific element type
Array methods Cast when TS can't narrow array item types

Important Notes

Template Type Checking Requirements

Template type checking is enabled when:

  1. <script lang="ts"> or <script setup lang="ts"> is used
  2. Vue Language Server (Volar) is active in your IDE
  3. For webpack: vue-loader >= 16.8.0 is required

Avoid Excessive Casting

If you find yourself casting frequently in templates, consider:

  • Moving logic to computed properties
  • Using type guards in the script section
  • Refactoring data structures to be more specific

Reference

Source: SKILL.md on GitHub

No alerts17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill is a comprehensive collection of educational debugging guides and best practices for Vue 3 developers. It contains no executable code or malicious instructions and focuses solely on diagnosing common runtime errors and performance issues.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    140 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at a5fc891. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 8 months ago

README badge

README badge for hyf0/vue-skills/vue-debug-guides

Guides for diagnosing and fixing Vue 3 runtime errors, reactivity bugs, async failures, and hydration issues across components, templates, watchers, forms, and lifecycle hooks. Covers specific failure modes like stale watchers, ref unwrapping edge cases, v-model sync problems, and SSR mismatches with concrete reference links for each issue.

Generated from the current SKILL.md.

Does this skill cover Vue 2?
No. This skill is specific to Vue 3 debugging and error handling.
What should I use for Vue development best practices instead of debugging?
The skill references a separate `vue-best-practices` skill for development best practices and common gotchas.
Does this cover SSR and hydration issues?
Yes. The skill includes guides for diagnosing and fixing SSR rendering differences and hydration bugs.
Can this help with async watcher and watchEffect problems?
Yes. The skill covers async operation stale data, dependency tracking after await, and proper flush timing for watchers.
Does this address v-model and form-related issues?
Yes. The skill includes guides for v-model initial values, textarea interpolation, IME composition, and custom checkbox form submission.

Generated from the current SKILL.md. These answers refresh after source changes.