-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Export all TS types used by public API #2020
Comments
You already have the types needed to write that function. import { FunctionalComponent, ExtractPropTypes } from 'vue'
function withProps<T>(props: T, fn: FunctionalComponent<ExtractPropTypes<T>>) {
// ...
} |
Ok, thank you very much for such a nice response. But what about other use-cases I personally couldn't come up with? |
Still, for the exact use-case I provided, current types provide some weird results: Oh, and array props don't work at all this way: But that's not my point. As stated in the original issue post, my point is that there are always types that need to be exposed, but aren't. And fulfilled requests for exposing some particular types keep piling up in the changelog (10+ cases as of time of this writing), because it turns out at some point that some types are needed to test/extend/use the API. |
Hey, @pikax, thanks for the answer. Can you, please, make a somewhat convincing case on why "internal types" should not be exposed? I get that there are some types that are used only by internal APIs that are not exposed, and it may be okay. In my opinion, exposed types allow for:
One could argue about breaking changes in internal typings. But then, if such a situation occurs on types that are used in public API (like I think I didn't quite state it right in the first place, that I'm only talking about types that are used by public APIs. I'll edit the original post to better represent this point.
For example, the My project that I'm migrating to Please note, that I'm not having troubles or asking for help regarding Vue types. |
IMO is to make the vue types bloated with unnecessary types, this will prevent the user to try to access internal APIs or write code with a type that might change. This simplify users life with less types to be import, such as You haven't given any good arguments on why "all" types should be exported.
Such as?
You should be using the
That's exactly the reason you shouldn't be accessing "internal" types, vue2 types are different from vue3, there's works to bring them closer.
You example and the subsequent reply to the solution provided, shows that you are having troubles with the vue types,
If you still need help extracting the types, please use Just to make it clear, "export all TS types" is not correct, export specific types which are not being currently exported is still open for discussion. If you have a specific type (which you don't have access currently), you can create a PR to export it, it will be discussed case by case. If you still not happy with my response, please create an RFC to bring this discussion to the community. |
Ok, thank you for a very detailed reply.
I agree with this specific statement, which is why I've already corrected my point to "export all TS types used by public API" that better reflects my intentions and concerns.
All of them have a couple of things in common:
As I stated, it has extra type information that I don't need.
I didn't try to, because I was only giving arguments on why "all types of public APIs" should be exported.
Not with public APIs that use internal types.
withProps(
{
msg: {
required: true,
type: String
}
} as const,
props => {
props.msg
}
) This is syntactic burden in userland, can be avoided by using
I've already come up with a solution myself, I just wanted to prove a point. |
I found out this thread in the process of migrating my project from Vue 2 to Vue 3. In Vue 2, I've used |
@binhonglee const Comp = defineComponent({ /* component definition */}
type CompTypeDefinition = typeof Comp; // should be DefineComponent
type CompInstance = InstanceType<CompTypeDefinition>
|
My current use case is mainly to get input element values through refs or to get the element itself to set focus. As far as I know, refs are still not strictly type aware so it requires a lot of typecasting and repeating it by hand is a little tedious. So I made some sort of a helper class to deal with that. Your suggestion seems to only apply if I know the specific component I'll be passing around instead of generically any Vue component. I tried using Edit: Also seems like |
What problem does this feature solve?
Let's say, there's a situation sometime that requires a user of Vue 3 to make a certain wrapper or extension for the standard public API.
For example...
Currently, there's only one way to define props for a functional component, as stated in docs:
This is far from perfect for user experience, and is definitely in need of some sort of a wrapper (with type inference, preferably).
Something like
The
defineComponent
function is public and uses some typings to provide type information for the component and props alike, which would also be useful for this wrapper.I've written this wrapper myself for my project only, but have encountered an issue - currently most of the types of
@vue/runtime-core
are internal and are not exported, therefore making a job of creating such wrappers practically an impossible choice.So, now you either:
@vue/runtime-core/dist/runtime-core.d.ts
into the project, because most of the types used indefineComponent
are not exposed.So, with all types exported from d.ts files, the end user gains the ability to more freely understand and expand upon the standard Vue 3 API without the need to write boilerplate code or copy half of the typings into their own project.
The wrapper is still possible to create without vue typings, it's just an example. But it still would lack some typing clarity the internal types could provide...
What does the proposed API look like?
Export all types without exceptions from
d.ts
files so users can more freely extend and compose current API properly (this was the whole point from the start, right?)...This can be done with existing APIs, as no new APIs need to be added - just a couple of exports for compile-time types here and there.
I get that there are some types that are used only by internal APIs that are not exposed, and it may be okay.
But there are types used by public APIs (like
defineComponent
), that are still not exposed.So, not exposing types used by public APIs is like not exposing some part of the already exposed API.
In my opinion, exposed types allow for:
P.S. If this gets any positive feedback - I'll gladly propose a PR myself.
P.P.S. The issue itself is more about the lack of type exports than the wrapper itself - it's provided as more of an example of what's to come (in terms of user experience problems) when Vue 3 makes it to production and is adopted by industry-scale projects.
The text was updated successfully, but these errors were encountered: