Skip to content

feat: Strict type children in slots - #734

Open
pikax wants to merge 2 commits into
masterfrom
slots-strict-type
Open

pikax wants to merge 2 commits into
masterfrom
slots-strict-type

Conversation

@pikax

@pikax pikax commented Jan 8, 2025

Copy link
Copy Markdown
Member

Summary

Allow for tools to enforce strict children type for Slots, by allowing to describe what type of children can be used in the slot.

Links


Important: Do NOT comment on this PR. Please use the discussion thread linked above to provide feedback, as it provides branched discussions that are easier to follow. This also makes the edit history of the PR clearer.

@ubugeeei

Copy link
Copy Markdown
Member

Implementation tracking (Draft)

Project Pull request / scope Target Validation
language-tools, including vue-component-type-helpers vuejs/language-tools#6206 v3.4 (minor development) Local: 228 tests passed, 4 skipped; lint passed. GitHub checks pending.
docs vuejs/docs#3464 main (no minor branch exists) Local build and type check passed. GitHub checks pending.
core No change required for this implementation: defineSlots already preserves its declared function types; checking and render metadata are generated by language-tools. Reviewed minor No runtime or macro-compilation change.

The proposed public spelling is Renders<typeof Comp>, with Renders<typeof Comp<T>> for generic components. It addresses the same composition-contract use case as Flow's render types: Renders<typeof Comp>, Renders<typeof Comp> | undefined, and Renders<typeof Comp>[] correspond conceptually to renders Comp, renders? Comp, and renders* Comp.

The implementation supports component unions with correlated props, imported interfaces/aliases/re-exports, inferred and explicit generic arguments, tuples and variadic tuples, text, native namespaces, and every v-if / v-else-if / v-else path. Wrapper inference follows actual forwarded slot content and fallbacks, and distinct SFC identities prevent unrelated same-shaped components from matching.

Regression coverage includes exact diagnostic locations, option-off behavior, a 24-wrapper chain, declaration emission checked by plain TypeScript with skipLibCheck: false, and a separate Vue declaration consumer. Components without generated metadata and DOM interfaces retain TypeScript's structural rules; arbitrary VNode render functions do not reveal their roots, and unprovable wrapper cycles fail restricted checks.

Both PRs remain Draft for RFC/API review and coordinated release. This comment tracks implementation status; design discussion remains in #733.

@lizhan12

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants