-
-
Notifications
You must be signed in to change notification settings - Fork 414
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
Strongly-typed inheritAttrs #4882
Comments
Potential work-around for communityAs this is a type-only solution with no runtime change, there might be a way to apply this in user-land until Vue fixes this issue. Warning This is new and not battle-tested. Use with caution. The idea is simple: re-export the Vue component with an altered typing. Let's say you have two components You'll need to create a The typing is where this becomes quite ugly, as Vue types are very complex. You'll need a way to extract Props types. Package vue-component-type-helpers has type ComponentProps<T> =
T extends new (...args: any) => { $props: infer P; } ? NonNullable<P> :
T extends (props: infer P, ...args: any) => any ? P :
{}; Then you'll need types to hide props from type Inherits<A, B> = A & Omit<B, keyof A>;
type FallthroughProps<A, B> = Inherits<ComponentProps<A>, ComponentProps<B>>; Finally you can create a fake wrapper type. type HOC<A extends (...args: any) => any, B> = (props: FallthroughProps<A, B>, ...args: any) => ReturnType<A>; And here's the example from before: // File: wrapper.ts, import this instead of wrapper.vue
import Wrapper from "wrapper.vue"
import type Inside from "inside.vue"
export default Wrapper as HOC<typeof Wrapper, typeof Inside> This even works when export const FallthroughWrapper = Wrapper as <T>(
props: FallthroughProps<typeof Wrapper<T>, typeof Inside<T>>,
...args: any
) => ReturnType<typeof Wrapper<T>>; This pattern can be adapted to more generic arguments and relationships between |
Well, I'm closing this issue as it seems I missed an update two months ago! It's sad it's an opt-in because of poor performance, as it's very useful, but it's better than nothing :) Hopefully the perf can be improved and become a default in the future! I can't seem to get that setting to work, but that's another issue, though 😂 |
What problem does this feature solve?
Currently it's difficult to automatically strongly-type components that wrap other components (aka HOC).
This is a common complaint, e.g. this RFC links to many issues: vuejs/rfcs#479
If a component
Out
wraps a componentIn
, the goal would be that tooling shows strong typing forIn
props onOut
, even thoughOut
doesn't declare them.What does the proposed solution look like?
My idea is not intrusive and would benefit everyone with zero code change.
SFC compiler and runtimes remain unchanged. They work fine and there's no need to modify them.
What happens is that in
Out
, undeclared props end up inattrs
, and withinheritAttrs: true
they are copied toIn
props.Tooling is modified to change the declared props type of
Out
.Let's say components have props of type
PO
andPI
respectively.When a component has
inheritAttrs: true
and a single root component in template, instead of declaringOut<PO>
, it's type is declared asOut<Inherit<PI, PO>>
.The secret sauce is a mapped type
Inherit
that copies properties that are not re-declared byPO
. Here's my take on it:These apparent props are a bit of lie, but the typing actually matches the runtime behaviour so I think it's a simple solution to a common issue.
The text was updated successfully, but these errors were encountered: