Open
Description
Vue - Official extension or vue-tsc version
3.0.1
VSCode version
1.101.2
Vue version
3.5.17
TypeScript version
5.8.3
System Info
System: OS: macOS 15.5 Shell: 4.0.2 - /opt/homebrew/bin/fish Binaries: Node: 20.5.0 Yarn: 1.22.22 npm: 9.8.0 pnpm: 10.11.0 Browsers: Chrome: 138.0.7204.93 Safari: 18.5
Steps to reproduce
pnpm create vue@latest
- Open
src/components/HelloWorld.vue
and put in<script lang="ts"></script> <script setup lang="ts"> defineOptions({}); export interface MyProps { msg: string; } const { msg } = defineProps<MyProps>() </script>
What is expected?
No errors, since 'interface hoisting for defineProps
' is a supported feature as per #2421.
Expected codegen
/// <reference types="../../node_modules/.vue-global-types/vue_3.5_0_0_0.d.ts" /> export interface MyProps { msg: string; } debugger/* PartiallyEnd: #3632/both.vue */ export default await (async () => { defineOptions({}); type __VLS_Props = MyProps; const { msg } = defineProps<__VLS_Props>() debugger/* PartiallyEnd: #3632/scriptSetup.vue */ // @ts-ignore declare const { defineProps, defineSlots, defineEmits, defineExpose, defineModel, defineOptions, withDefaults, }: typeof import('vue'); type __VLS_PublicProps = __VLS_Props; const __VLS_ctx = {} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>; let __VLS_elements!: __VLS_IntrinsicElements; type __VLS_LocalComponents = & typeof __VLS_ctx; let __VLS_components!: __VLS_LocalComponents & __VLS_GlobalComponents; type __VLS_LocalDirectives = & typeof __VLS_ctx; let __VLS_directives!: __VLS_LocalDirectives & __VLS_GlobalDirectives; type __VLS_Slots = {}; type __VLS_InheritedAttrs = {}; type __VLS_TemplateRefs = {}; type __VLS_RootEl = any; const __VLS_self = (await import('vue')).defineComponent({ setup() { return { }; }, __typeProps: {} as __VLS_PublicProps, }); return (await import('vue')).defineComponent({ setup() { return { }; }, __typeProps: {} as __VLS_PublicProps, }); })();/* PartiallyEnd: #4569/main.vue */ type __VLS_TypePropsToOption<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? { type: import('vue').PropType<Required<T>[K]> } : { type: import('vue').PropType<T[K]>, required: true } };
What is actually happening?
TS1184 Modifiers cannot appear here
on the line export interface MyProps {
.
Actual (broken) codegen
/// <reference types="../../node_modules/.vue-global-types/vue_3.5_0_0_0.d.ts" /> debugger/* PartiallyEnd: #3632/both.vue */ export default await (async () => { defineOptions({}); export interface MyProps { msg: string; } type __VLS_Props = MyProps; const { msg } = defineProps<__VLS_Props>() debugger/* PartiallyEnd: #3632/scriptSetup.vue */ // @ts-ignore declare const { defineProps, defineSlots, defineEmits, defineExpose, defineModel, defineOptions, withDefaults, }: typeof import('vue'); type __VLS_PublicProps = __VLS_Props; const __VLS_ctx = {} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>; let __VLS_elements!: __VLS_IntrinsicElements; type __VLS_LocalComponents = & typeof __VLS_ctx; let __VLS_components!: __VLS_LocalComponents & __VLS_GlobalComponents; type __VLS_LocalDirectives = & typeof __VLS_ctx; let __VLS_directives!: __VLS_LocalDirectives & __VLS_GlobalDirectives; type __VLS_Slots = {}; type __VLS_InheritedAttrs = {}; type __VLS_TemplateRefs = {}; type __VLS_RootEl = any; const __VLS_self = (await import('vue')).defineComponent({ setup() { return { }; }, __typeProps: {} as __VLS_PublicProps, }); return (await import('vue')).defineComponent({ setup() { return { }; }, __typeProps: {} as __VLS_PublicProps, }); })();/* PartiallyEnd: #4569/main.vue */ type __VLS_TypePropsToOption<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? { type: import('vue').PropType<Required<T>[K]> } : { type: import('vue').PropType<T[K]>, required: true } };
Any additional comments?
The error only happens when three things are true:
- There is a
<script lang="ts">
tag (empty ones are fine) along with<script setup lang="ts">
.- Removing the tag will fix the error.
- There is an
export interface
orexport type
inside<script setup lang="ts>
.- Also true for
export const
, but I'm not sure that's supported in<script setup>
anyway.
- Also true for
- There is a compiler macro that appears before the
export
item.- Any macro seems to reproduce:
defineOptions
,defineEmits
,defineExpose
, etc. - The order is important. The error is gone when I move
defineOptions({})
after the interface export.
- Any macro seems to reproduce: