-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to import interface for defineProps #4294
Comments
We'll mark it as an enhancement for the future. |
希望Vue团队能早日支持,现在使用vue3.2 defineProps()为Props定义单个单个类型还可以,若涉及到联合或交叉等复杂类型 defineProps就会编译错误, 这对于类型扩展是一件非常糟糕的事情 |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I have found a workaround in my case (#4758) that allows you to provide typing to your props (or its nested members) with an interface, even if the interface is imported from another file. The workaround is to rename your interface to something else. import { Post as PostRenamed } from '@/models/forum/PostDef';
interface Props {
Args: {Post: PostRenamed };
}
const props = withDefaults(defineProps<Props>(), {}); I noticed that you have to do this renaming workaround if the interface name appears anywhere within your |
I also find a workaround, just use |
Despite a fairly similar setup to @phasetri's issue, I'm finding that the properties of the interface I'm trying to import resolve as Control example: <script setup lang="ts">
interface IThingie {
serial: string,
id: string,
startDate: Date | null,
endDate: Date | null
}
const props = withDefaults(defineProps<IThingie>(),{});
</script>
// In vue-devtools (values from route params)
props
{
"id": "123",
"serial": "asdfa",
"startDate": null,
"endDate" null
} @phasetri's solution: <script setup lang="ts">
import { IThingie as InterfaceRenamed } from './types';
interface Props {
Args: { IThingie: InterfaceRenamed }
}
const props = withDefaults(defineProps<Props>(),{});
</script>
// In vue-devtools (values from route params)
props
{
"Args": "undefined"
}
attrs
endDate: null
id: 123
serial: "asdfa"
startDate: null In my team's particular case, we want to keep the interface(s) outside of the components and use them as generics. In that way, we'd be able to import them elsewhere such as services as needed. We can't seem to export them from a separate I guess all of this is to say a few things:
That last one comes with some ignorance surrounding the difficulties of compiling Typescript from within Vue and the core team's release cadence, so I respect any disagreement with that request. It's just that, as a user, it does feel irksome that I can't import an interface from a file using a syntactical mode that's supposed to make Typescript adoption simpler. |
To follow up on @cdvillard 's commentary -- In a world where there are many packages interacting with each other, such as Jest testing and Storybook's stories, being able to maintain a reusable interface that can be imported in our .vue components, and our other .ts files, makes a massive difference in our ability to adopt. If it's possible to see this on a roadmap, that would greatly help with enterprise adoption. I love the simplicity and elegance of Vue, and in particular the new typescript features, but this is a major sticking point for us. I appreciate all the hard work, I really do. But this is a bigger issue than it sounds. |
If you are using Vite, you can use this plugin https://github.com/wheatjs/vite-plugin-vue-type-imports as a patch until this is officially supported. |
@wheatjs , I gave the plugin a try before posting, but I couldn't get it working. Let me try again and see if I can at least post an issue with a basic recreation. I'm not sure if part of the issue had to do with running the compat build at the time, but that's no longer the case. I appreciate that you've made this though! Created this issue on the plugin repo: wheatjs/vite-plugin-vue-type-imports#4 |
I've gone all-in on Vue 3, TypeScript and the Composition API. However, the restriction of requiring object literals and interfaces being defined in the SFC source severely limits reuse. I am attempting to define a common props interface in a composable module to replace the need for a mixin, extending Props interfaces as in #4989, and using mergeProps to merge an object with default values via withDefaults(). As I soon learned, that won't work. So the only solution is to either go crawling back to mixins and the Options API, or repeat literal code in dozens of files, inviting a maintenance nightmare. Unless anyone has a 3rd option, for which I'm open to suggestions. The vite plugin mentioned above does not solve these issues for me. |
This severely hinders wrapping 3rd party components via type script, as you have to copy and paste the interfaces into your SFC, greatly increasing maintenance burdens and destroying readability. Unless there is an easier way to do this?
e.g. the above is impossible currently. |
Is there any way we can donate for specific issues? Or maybe open an issue hunt? I'd love to put in some extra donations specifically towards this ticket. |
This comment has been minimized.
This comment has been minimized.
This comment was marked as abuse.
This comment was marked as abuse.
PR got merged 3 days ago: #8083 |
closed via #8083 |
how to import interfaсe for defineEmits? |
can not get OtherProps type OtherProps = Pick<InputProps, 'suffixIcon' | 'prefixIcon' | 'clearIcon'>
export interface SearchProps extends OtherProps {
modelValue?: string | number;
placeholder?: string;
clearable?: boolean;
width?: string | number;
popoverCfg?: PopoverProps;
visible: boolean
} |
TS complex types are not supoorted Update: Probably I am wrong. Some built-in types such as |
Hi @Miofly well you should open a new issue because this one is closed. But you can link this one to from the new issue |
@Miofly open a new issue bc I too am having this issue. If I import the interface it does not work. If I define the interface inside the same file as the component, no issue. My current workaround is:
|
I am still not able to set defaults through a reference and opened a issue for it. Am I correct in thinking it is not possible yet or am I doing something wrong? |
what's the latest on this issue? |
I works now. I think since vue 3.3 |
这个问题现在有办法解决了吗?我还是遇到这样的问题 |
@hou-moliy 更新到3.3… |
English please :-) |
I do not see how the PR that addressed this issue actually resolves the underlying problem. I believe this is marked as closed incorrectly by the Github PR process. |
@OliverRC It should work now. |
@so1ve can you check this link? head to Vue SFC playground for import external types for defineProps |
Hi @sadeghbarati, The type you imported extends |
I can confirm that it looks to be working on 3.3 |
Then how can we wrap native button html element? How to use |
@tombohub I'm working on an unplugin: https://github.com/so1ve/unplugin-vue-complex-types which uses typescript compiler's API to resolve such types. But it is not useable now since it has very very huge performance issues. |
what about vue2.7? |
It won't happen in 2.7 You need to migrate. Note: vue 2.x is end of life at the end of the year. Don't expect any major change now. |
update:
please see:
#7394
#4294 (comment)
Version
3.2.1
Reproduction link
https://github.com/Otto-J/vue3-setup-interface-errors/blob/master/src/components/HelloWorld.vue
Steps to reproduce
clone: git clone
start: yarn && yarn dev
open: master/src/components/HelloWorld.vue
modify: import interface from './types'
What is expected?
no error
What is actually happening?
[@vue/compiler-sfc] type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type.
in chinese:
我想把 props的interface抽出去,但是会报错,如果interface组件里定义的就正常渲染
in english:
I want to extract the interface of props, but an error will be reported. If the interface component is defined, it will render normally
The text was updated successfully, but these errors were encountered: