Skip to content

Strongly-typed inheritAttrs #4882

@jods4

Description

@jods4

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 component In, the goal would be that tooling shows strong typing for In props on Out, even though Out 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 in attrs, and with inheritAttrs: true they are copied to In props.

Tooling is modified to change the declared props type of Out.
Let's say components have props of type PO and PI respectively.
When a component has inheritAttrs: true and a single root component in template, instead of declaring Out<PO>, it's type is declared as Out<Inherit<PI, PO>>.

The secret sauce is a mapped type Inherit that copies properties that are not re-declared by PO. Here's my take on it:

type Inherit<In, Out> = Out & {
  [p in keyof In as Exclude<p, keyof Out>]: In[p]
}

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions