vite-plugin-vue-resolve-types

Resolve script setup defineProps types to runtime props in Vue SFC
1,057 22
Install
npm install vite-plugin-vue-resolve-types
Latest Version:0.0.4
Vue:3
License:MIT
Last Updated:Sep 23, 2026
Links: GitHub  ·  npm
Maintainer: aibayanyu

vue-resolve-types

Type-based Vue SFC macro resolver plugin for Vite.

It converts <script setup lang="ts"> / <script setup lang="tsx"> macro types into runtime declarations:

  • defineProps<Type>() -> defineProps({...})
  • withDefaults(defineProps<Type>(), defaults) -> defineProps(...)
  • defineEmits<Type>() -> defineEmits([...])

The runtime type resolution is powered by @v-c/resolve-types.

Install

pnpm add -D vite-plugin-vue-resolve-types

Usage

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { vueResolveTypes } from 'vite-plugin-vue-resolve-types'

export default defineConfig({
  plugins: [
    vueResolveTypes(),
    vue(),
  ],
})

Plugin Order (Important)

vueResolveTypes() must run before @vitejs/plugin-vue.

Reason:

  • this plugin rewrites <script setup> macro calls (defineProps / defineEmits) at the SFC source level
  • @vitejs/plugin-vue runs Vue SFC compilation (compileScript) afterwards
  • if vueResolveTypes() runs after vue(), the macro type information is already consumed and this plugin can no longer transform it

Recommended:

plugins: [
  vueResolveTypes(),
  vue(),
]

Do not use:

plugins: [
  vue(),
  vueResolveTypes(),
]

Example

defineProps<Type>()

<script setup lang="ts">
interface Props {
  foo: string
  count?: number
}

const props = defineProps<Props>()
</script>

Transformed (simplified):

const props = defineProps({
  foo: { type: String, required: true },
  count: { type: Number, required: false },
})

withDefaults(defineProps<Type>(), ...)

<script setup lang="ts">
interface Props {
  size?: number
}

const props = withDefaults(defineProps<Props>(), {
  size: 12,
})
</script>

Transformed (simplified):

const props = defineProps({
  size: { type: Number, required: false, default: 12 },
})

For dynamic defaults (e.g. imported defaults), the plugin injects Vue's mergeDefaults helper import when needed.

defineEmits<Type>()

<script setup lang="ts">
const emit = defineEmits<{
  (e: 'change', value: string): void
  (e: 'update:modelValue', value: number): void
}>()
</script>

Transformed (simplified):

const emit = defineEmits(["change", "update:modelValue"])

Options

vueResolveTypes({
  props: true,
  emits: true,
  isProd: false,
  include: (id) => id.endsWith('.vue'),
  ignoreTypes: [/EmitsProps$/],
})

props

  • Type: boolean
  • Default: true

Enable/disable defineProps<Type>() transform.

emits

  • Type: boolean
  • Default: true

Enable/disable defineEmits<Type>() transform.

include

  • Type: (id: string) => boolean

Custom file filter. If provided and returns false, the transform is skipped.

isProd

  • Type: boolean

Pass-through to the underlying Vue SFC type resolution context to align runtime props output with Vue production mode behavior.

customElement

  • Type: boolean | ((filename: string) => boolean)

Pass-through to align runtime props output with Vue custom element mode behavior.

fs

  • Type: { fileExists; readFile; realpath? }

Override file system access used when resolving imported types.

ignoreTypes

  • Type: (string | RegExp)[] | ((name: string, ctx: { filename: string }) => boolean)

Type names that must not become runtime props. A match contributes no members in an extends/intersection position and infers to null as a prop type, like /* @vue-ignore */, but it also works for types consumed from a published .d.ts where that comment is gone. Matched against the local reference name, so anchor your patterns: [/EmitsProps$/]. The identity wrapper VueIgnore<T> (exported by @v-c/util/dist/type) is always recognised regardless of this option.

Scope / Non-goals (current)

  • Focuses on type -> runtime props/emits conversion only.
  • Does not implement Vue compiler's full <script setup> transform pipeline.
  • Does not replace Vue's reactive destructure rewrite logic; destructure defaults are left for Vue compileScript to handle after this plugin.

Status

The package includes tests adapted from Vue compiler-sfc macro tests (defineProps, definePropsDestructure, defineEmits) for the type-to-runtime conversion scope.

License

MIT

Related Packages

@vitejs/plugin-vue

The official plugin for Vue SFC support in Vite.

333,357,380 686
vite-plugin-checker

Vite plugin that runs TypeScript type checker on a separate process.

133,975,562 1,242
@vitejs/plugin-vue-jsx

Provides Vue 3 JSX & TSX support with HMR.

93,663,827 686
vite-plugin-ssr

Like Next.js/Nuxt but as do-one-thing-do-it-well Vite plugin.

550,634 18
vite-plugin-md

Markdown for Vite

496,869 640

Version History

Version Released Vue License
0.0.4 >=3.3 MIT
0.0.3 >=3.3 MIT
0.0.2 >=3.3 MIT
0.0.1 >=3.3 MIT