fix(types): enable proper type narrowing for defineEmits (#13935)
close #13935
This PR fixes the type narrowing issue with defineEmits when using type-based declaration.
Summary by CodeRabbit
-
Refactor
- Improved type inference and streamlined internal type definitions for event emission handling in
defineEmits.
- Improved type inference and streamlined internal type definitions for event emission handling in
-
Tests
- Added comprehensive type-checking test coverage for
defineEmitswith type declarations to ensure correct payload types and event names are enforced.
- Added comprehensive type-checking test coverage for
✏️ Tip: You can customize this high-level summary in your review settings.
Walkthrough
The ShortEmits type in the runtime-core package is refactored from a complex intersection-based construction to a straightforward generic function signature. This change enables proper TypeScript type narrowing when using defineEmits with event declarations, allowing the compiler to correctly infer payload types for specific event keys. Type-checking tests are added to validate the narrowing behavior.
Changes
| Cohort / File(s) | Summary |
|---|---|
Type definition refactoring packages/runtime-core/src/apiSetupHelpers.ts |
Replaced complex ShortEmits type using UnionToIntersection<RecordToUnion<...>> with a simple generic function signature <K extends keyof T>(evt: K, ...args: T[K]) => void. Removed helper types RecordToUnion and import of UnionToIntersection from shared utilities. |
Type-checking tests packages-private/dts-test/setupHelpers.test-d.ts |
Added new test block validating defineEmits type narrowing for Issue #13935, including correct emit calls with specific payload types and @ts-expect-error cases for incorrect usages. |
Estimated code review effort
🎯 2 (Simple) | ⏱️ ~12 minutes
- Focused change affecting one core type definition with clear before/after semantics
- Type system changes require careful verification that the new signature properly enables narrowing
- Added tests provide direct validation of expected behavior
-
Areas needing attention: Verify that the new type signature correctly narrows in real-world TypeScript scenarios; confirm backward compatibility with existing
defineEmitsusage
Poem
🐰 A simpler path for types to trace,
No intersection loops—just function's grace,
When "open" calls, the args align,
No more ambiguous—the types now shine! ✨
Pre-merge checks and finishing touches
✅ Passed checks (5 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title accurately describes the main change: fixing type narrowing for defineEmits to properly resolve event-specific argument types. |
| Linked Issues check | ✅ Passed | The PR directly addresses issue #13935 by replacing the complex UnionToIntersection-based ShortEmits type with a straightforward generic function signature that enables proper type narrowing for event names and their corresponding argument types. |
| Out of Scope Changes check | ✅ Passed | All changes are scoped to the defineEmits type system; the main file modifies ShortEmits type definition and the test file adds type-checking tests validating the fix. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
📜 Recent review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between ebc4f0f1987298ef20ed4a97f62277637717f501 and ba68414e80bc25228727411580acd3de18b523bc.
📒 Files selected for processing (1)
-
packages-private/dts-test/setupHelpers.test-d.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages-private/dts-test/setupHelpers.test-d.ts (1)
packages/runtime-core/src/apiSetupHelpers.ts (1)
defineEmits(144-149)
🔇 Additional comments (1)
packages-private/dts-test/setupHelpers.test-d.ts (1)
636-653: Test structure is appropriate for validating type narrowing behavior.The test correctly uses
@ts-expect-errorguards to validate thatdefineEmitswith mapped event signatures properly enforces type checking for both correct payload types (emit('open', 123),emit('close', 'abc')) and rejects invalid cases (wrong payload types and unknown events). The test follows the established pattern in the file and adequately validates the fix for issue #13935.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
Would it be possible to still have 'open' / 'close' instead of evt: keyof __VLS_Emit
Size Report
Bundles
| File | Size | Gzip | Brotli |
|---|---|---|---|
| runtime-dom.global.prod.js | 103 kB | 39 kB | 35.1 kB |
| vue.global.prod.js | 161 kB | 58.9 kB | 52.6 kB |
Usages
| Name | Size | Gzip | Brotli |
|---|---|---|---|
| createApp (CAPI only) | 47 kB | 18.3 kB | 16.8 kB |
| createApp | 55.1 kB | 21.4 kB | 19.6 kB |
| createSSRApp | 59.4 kB | 23.2 kB | 21.1 kB |
| defineCustomElement | 60.7 kB | 23.1 kB | 21.1 kB |
| overall | 69.4 kB | 26.6 kB | 24.3 kB |