eslint-plugin-vue
eslint-plugin-vue copied to clipboard
vue/require-valid-default-prop not always detecting interface in seperate .ts file
Checklist
- [x] I have tried restarting my IDE and the issue persists.
- [x] I have read the FAQ and my problem is not listed.
Tell us about your environment
- ESLint version: v8.22.0
- eslint-plugin-vue version: 9.4.0
- Node version: v16.15.1
- Operating System: Windows 10 (64 bit) + WSL Ubuntu 18.04.2 LTS
Please show your full configuration:
{
"env": {
"browser": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "vue-eslint-parser",
"parserOptions": {
"ecmaVersion": "latest",
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"plugins": [
"vue",
"@typescript-eslint"
],
"rules": {
"vue/multi-word-component-names": "off",
"vue/no-reserved-component-names": "off",
"no-console": "off",
"no-debugger": "off"
}
}
What did you do?
// types/file.ts
interface Label {
label: string
plural: boolean
}
export { Label }
<script setup lang="ts">
import { Label } from '@/types/file.ts'
withDefaults(
defineProps<{
label?: string | Label
}>(),
{
// This appears to be incorrect but should be accepted
label: () => ({ label: 'label', plural: true }),
// This is correct
label: () => {
return { label: 'label', plural: true }
}
}
)
</script>
What did you expect to happen? Both ways of setting the default should be accepted.
What actually happened?
114:19 error Type of the default value for 'label' prop must be a string vue/require-valid-default-prop
When Label is in a different .ts file linting fails with the above error. When moving the definition of Label into the Vue file linting issue is solved. There appears to be a difference in behaviour depending on how you specify the function which is also not expected.
Repository to reproduce this issue
https://github.com/Nicolas-Yazzoom/eslint-plugin-vue-bug
Added repro
I think you need to define the type definition inside vue. https://vuejs.org/guide/typescript/composition-api.html#syntax-limitations
The following demo prints a warning to the console. https://sfc.vuejs.org/#eNp9UU1rwzAM/SvCl6TQJveQdgx23GE/wBe3VVqXxDay0g4y//cpX9BtsJOtJ+mh996gXkMo7j2qStXxRDYwROQ+QGvcZa8VR60O2tkueGIY4N0csYUEDfkOsqJsbIsFx0y7h+XrGzambznm2gGcsbEOP8iHWA8jAEIq2y8VRCbrLvA10429dMg32/HzPFlBvoH9AfJhrbPpzbYQ2p6MAEw9QppXk3Yb7bSry1mJ3C0FYxdawyjVMEzrSQbr8glXWzUL3HUmFLfondgxHaKXhrhQradpJX6NtVZX5hCrsozNaTTxFgtPl1J+BfWObYcFxm53JP+ISEKs1XTowlEKeEfaEbozEtJ/nL9G//Au+pNIWSIRCdYxUmNOuMQ2CVicnCMYgdXKo/ctGrFMeLTDz5+Jq/QNdRq/dA==
Hello there
From the docs:
"The interface or object literal type can contain references to types imported from other files, however, the generic argument itself passed to defineProps cannot be an imported type."
In this case the literal contains a reference to the Label interface imported from file.ts so I believe it should be allowed, no? Also, thank you for the simplified repro! :)
I'm not familiar with English, so I may have misunderstood the documentation, but it's true that vue's runtime is giving warnings. Since the warning is also displayed at runtime, I think we can judge that the rule is working correctly.
My bad, I misread the error. So this means label: () => ({ label: 'label', plural: true }) and label: () => { return { label: 'label', plural: true }} are not functionally equivalent? I used to do this in Vue 2 all the time without issue. Is there a difference?
I didn't realize it.
I think it's a false negative in the rule that the label: () => { return { label: 'label', plural: true }} is not warned.
@Nicolas-Yazzoom Yes, they are functionally equivalent.
This was probably fixed in v9.13.0. I'll close this issue for now, feel free to comment or open a new issue if it is not fixed.