<script setup>: Prop Member "Args.Post" is conflicting with "Post" import from PostDef.ts
Version
3.2.19
Reproduction link
Steps to reproduce
yarn global add @vue/cli
vue create my_project
Select these options when prompted:
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, Router, Vuex, CSS Pre-processors
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? No
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass)
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
cd my_project
cd src/components
touch PostDef.ts
touch PostFc.vue
Content of PostDef.ts:
export interface Post {
Message: string;
}
Content of PostFc.vue:
<script setup lang="ts">
import {
Post,
} from "./PostDef";
interface Props {
Args: {Post: Post};
}
const props = withDefaults(defineProps<Props>(), {});
</script>
<template>
{{Args.Post}}
</template>
Within the auto-generated HelloWorld.vue, add a PostFc instance anywhere on the page
<script lang="ts">
import { defineComponent } from 'vue';
import PostFcVue from './PostFc.vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String,
},
components: {
PostFc: PostFcVue
}
});
</script>
<template>
...
...
...
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
<PostFc :Args="{Post: {Message: 'Hello World!!!'}}"></PostFc>
</div>
</template>
Then run the app:
yarn
yarn serve
What is expected?
No warnings should be reported when yarn serve
finishes compiling the app.
What is actually happening?
When yarn serve
finishes compiling the app, it will report a warning that PostDef.ts does not have a reference to Post:
warning in ./src/components/PostFc.vue?vue&type=script&setup=true&lang=ts
"export 'Post' was not found in './PostDef'
Note that the warning is not visible in the reproduction link; you have to reproduce it on your local machine.
I was able to reproduce the same problem by creating a Vite project instead of Vue-CLI project.
The problem is particularly serious in Vite as the warning gets reported on the browser console, and cause the whole HelloWorld page to not load at all.
You can quickly make the warning go away by modifying the template in PostFc.vue such that {{Args.Post}} does not reference Post
at all --- for example: {{Args}}
I think I found the reason why:
https://v3.vuejs.org/api/sfc-script-setup.html#typescript-only-features
Currently complex types and type imports from other files are not supported. It is theoretically possible to support type imports in the future.
Is there some other way that I can use to specify complex types for my prop members?
Is there some other way that I can use to specify complex types for my prop members?
You could try to use like this:
<script lang="ts">
export interface Post {
Message: string;
}
</script>
<script setup lang="ts">
interface Props {
Args: {Post: Post};
}
const props = withDefaults(defineProps<Props>(), {});
</script>
<template>
{{Args.Post}}
</template>
That works.
Interesting, I also found that you can create the same warning using this:
<script lang="ts">
import {
Post,
} from "./PostDef";
</script>
<script setup lang="ts">
interface Props {
Args: {Post: any};
}
const props = withDefaults(defineProps<Props>(), {});
</script>
<template>
{{Args.Post}}
</template>
Either way, I prefer putting my interfaces into a separate file; I'll try working around the problem in the meantime.