Vue Type Checker
vue-tsc is a command-line tool designed to integrate TypeScript's `tsc` compiler with Vue's Single File Components (SFCs). It functions as a wrapper around `tsc`, enabling full TypeScript type-checking and declaration file generation for `.vue` files by transforming them into virtual TypeScript code. The current stable version is 3.2.7, part of the actively developed `vuejs/language-tools` monorepo, receiving frequent updates with several patch releases per month. Its key differentiator is providing robust, performant type-checking for Vue applications within existing TypeScript ecosystems, leveraging `tsconfig.json` for configuration. It requires TypeScript 5.0.0 or higher as a peer dependency.
Common errors
-
Module not found: Error: Can't resolve './MyComponent.vue' in '...' OR Cannot find module './MyComponent.vue' or its corresponding type declarations.
cause TypeScript (tsc) does not natively understand `.vue` file imports. This typically indicates `vue-tsc` is not correctly integrated or the project's `tsconfig.json` is misconfigured.fixEnsure `vue-tsc` is installed and configured in your `package.json` scripts (e.g., `"type-check": "vue-tsc --noEmit"`) and that your `tsconfig.json` includes `"*.vue"` in its `include` array, along with appropriate `vueCompilerOptions`. -
The 'typescript' package is not installed or its version is less than 5.0.0.
cause `vue-tsc` has a strict peer dependency on TypeScript version 5.0.0 or higher.fixInstall or upgrade TypeScript to version 5.0.0 or newer: `npm install typescript@^5.0.0 --save-dev` (or `yarn add typescript@^5.0.0 --dev`). -
Property 'someProp' does not exist on type 'VueComponentInstance' (or similar type error within a Vue template or script).
cause Incorrect type inference for props, data, or methods within a Vue component, often due to missing `defineProps` or `defineEmits`, or incorrect type definitions.fixVerify that your Vue component's props and emits are correctly defined using `defineProps` and `defineEmits` with explicit generic type arguments in `<script setup>`, and ensure any custom types are properly imported and available.
Warnings
- breaking vue-tsc requires TypeScript version 5.0.0 or higher. Projects using older TypeScript versions will fail during installation or execution.
- gotcha vue-tsc is primarily a CLI tool. While it offers a programmatic `run` function, its API is minimal and designed for integrating the CLI, not for fine-grained language service control. For advanced programmatic usage, consider `@vue/language-core` or `@vue/language-service` packages.
- gotcha By default, `vue-tsc` only processes `.vue` files. If you use custom extensions (e.g., `.md`, `.vitepress`) for Vue components, you must explicitly list them in `vueCompilerOptions.extensions` in your `tsconfig.json`.
- gotcha vue-tsc internally transforms `.vue` files into virtual TypeScript code. This means you won't find corresponding `.ts` files on disk for your Vue SFCs during compilation, which can be confusing if you expect traditional compiler output.
Install
-
npm install vue-tsc -
yarn add vue-tsc -
pnpm add vue-tsc
Imports
- run
const { run } = require('vue-tsc')import { run } from 'vue-tsc' - VueCompilerOptions
import type { VueCompilerOptions } from 'vue-tsc' - Diagnostic
import type { Diagnostic } from 'vue-tsc'
Quickstart
import { run } from 'vue-tsc';
import * as path from 'path';
import * as fs from 'fs';
// Create a dummy tsconfig.json for demonstration if not present
const tsconfigPath = path.resolve('./tsconfig.json');
if (!fs.existsSync(tsconfigPath)) {
fs.writeFileSync(tsconfigPath, JSON.stringify({
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "bundler",
"strict": true,
"jsx": "preserve",
"lib": ["esnext", "dom"],
"types": ["node", "vue"]
},
"vueCompilerOptions": {
"extensions": [".vue"]
},
"include": ["./**/*.ts", "./**/*.d.ts", "./**/*.vue"]
}, null, 2));
}
// Create a dummy Vue SFC for type checking
const vueFilePath = path.resolve('./MyComponent.vue');
if (!fs.existsSync(vueFilePath)) {
fs.writeFileSync(vueFilePath, `
<script setup lang="ts">
import { ref } from 'vue';
const message: string = ref('Hello Vue 3 and TypeScript').value;
// Intentional error for demonstration: assign number to string
// const errorVal: string = 123;
</script>
<template>
<div>{{ message }}</div>
</template>
`);
}
console.log('Running vue-tsc programmatically with --noEmit...');
// Execute vue-tsc with command-line arguments
try {
run({
args: ['--noEmit', '--project', tsconfigPath] // Equivalent to 'vue-tsc --noEmit --project ./tsconfig.json'
});
console.log('vue-tsc completed successfully (noEmit). No type errors found.');
} catch (e) {
console.error('vue-tsc encountered an error:', e.message);
console.error('Check MyComponent.vue for type errors or tsconfig.json configuration.');
process.exit(1);
}