Hone logo
Hone
Problems

Seamless Vue 3 Type Checking with vue-tsc

This challenge focuses on integrating vue-tsc, the TypeScript compiler for Vue, into a Vue 3 project. Successfully integrating vue-tsc will ensure that your Vue components and their associated TypeScript code are type-checked during development and build processes, catching potential errors early and improving code quality.

Problem Description

Your task is to set up and configure vue-tsc within a new Vue 3 project. This involves installing the necessary dependencies, configuring your tsconfig.json file to work seamlessly with Vue Single File Components (SFCs), and demonstrating that vue-tsc can successfully identify and report type errors within Vue components. The integration should be robust enough to be used in a typical development workflow.

Key Requirements:

  • Installation: Install vue-tsc and any other required TypeScript or Vue-related packages.
  • Configuration: Properly configure tsconfig.json to enable type checking for .vue files.
  • Error Detection: Create a sample Vue component with a deliberate type error and verify that vue-tsc correctly identifies and reports it.
  • Command Line Integration: Ensure vue-tsc can be run from the command line to perform type checking.

Expected Behavior:

When vue-tsc is executed, it should:

  • Parse and type-check all .vue files in the project, including <script setup>, <script>, <template>, and <style lang="scss"> (if applicable and configured).
  • Report any TypeScript type errors found within these files.
  • Exit with a non-zero status code if errors are found, and a zero status code if no errors are found.

Edge Cases:

  • Different Script Block Types: Ensure type checking works correctly with both <script setup> and <script> blocks.
  • Props and Emits: Verify that props defined with defineProps and emits defined with defineEmits are correctly type-checked.
  • Template Expressions: Confirm that type checking extends to expressions within the <template> section.

Examples

Example 1:

Scenario: A simple Vue component with a prop that is expected to be a number but receives a string.

Input:

A Vue project with the following MyComponent.vue:

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

interface Props {
  count: number;
}

const props = defineProps<Props>();

// Attempt to pass a string to the number prop
const invalidCount = '5';
</script>

<template>
  <div>
    <p>Count: {{ props.count }}</p>
    <p>Invalid Count: {{ invalidCount }}</p>
  </div>
</template>

Expected Output (from running vue-tsc):

[vue-tsc] src/components/MyComponent.vue:10:16 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
  Type 'string' is not assignable to type 'number'.

10 const props = defineProps<Props>();
                  ^^^^^^^^^

[vue-tsc] src/components/MyComponent.vue:15:26 - error TS2322: Type 'string' is not assignable to type 'number'.

15 <p>Invalid Count: {{ invalidCount }}</p>
                          ^^^^^^^^^^

[vue-tsc] Found 2 errors.

Explanation: vue-tsc correctly identifies that props.count (which expects a number) is being implicitly assigned a string value from invalidCount in the template, and also that the invalidCount variable itself is being declared as a string when it's later referenced in the template where a type mismatch might occur if it were directly interacting with a typed value. (Note: The specific error message might vary slightly between vue-tsc versions, but the core issue of type mismatch should be highlighted).

Example 2:

Scenario: A component using defineEmits with incorrect payload typing.

Input:

A Vue project with the following EmitterComponent.vue:

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

// Define emits with a specific payload type for 'update'
const emit = defineEmits<{
  (e: 'update', value: number): void;
}>();

const handleClick = () => {
  // Attempt to emit with a string payload, not a number
  emit('update', 'new value');
};
</script>

<template>
  <button @click="handleClick">Update</button>
</template>

Expected Output (from running vue-tsc):

[vue-tsc] src/components/EmitterComponent.vue:11:10 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
  Type 'string' is not assignable to type 'number'.

11   emit('update', 'new value');
            ^^^^^^^^^^^^^^^^^^^^^

[vue-tsc] Found 1 error.

Explanation: vue-tsc detects that the emit function, configured to expect a number for the 'update' event, is being called with a string.

Constraints

  • Vue Version: Vue 3.x
  • TypeScript Version: Latest stable version compatible with Vue 3.
  • Project Setup: Assume a standard Vue 3 project structure created with create-vue (or similar).
  • Dependencies: Only standard build tools (e.g., Vite) and official Vue/TypeScript packages are allowed.

Notes

  • Refer to the official vue-tsc documentation for specific configuration options.
  • Pay close attention to the compilerOptions within your tsconfig.json.
  • You will need to add a script to your package.json to easily run vue-tsc.
  • Consider how vue-tsc integrates with your chosen build tool (e.g., Vite). You might need additional configuration for the build process itself, but the primary focus of this challenge is the vue-tsc setup.
Loading editor...
typescript