Skip to content

Conversation

@edison1105
Copy link
Member

@edison1105 edison1105 commented Nov 6, 2025

close #14056

Summary by CodeRabbit

  • Tests

    • Added test coverage for type behavior with never prop declarations.
  • Bug Fixes

    • Improved type inference for optional boolean props in defineProps, ensuring stricter and more accurate TypeScript hints for prop type narrowing.

@coderabbitai
Copy link

coderabbitai bot commented Nov 6, 2025

Walkthrough

Modifies the BooleanKey type in the defineProps type system to add a conditional check that ensures boolean keys are only selected when the property type is strictly boolean, not when combined with undefined. Adds a type test case validating the handling of properties declared as never.

Changes

Cohort / File(s) Change Summary
Test additions
packages-private/dts-test/setupHelpers.test-d.ts
New test block "defineProps w/ never prop" validates type inference when props include never types, asserting that foo?: never resolves to never | undefined and bar: number resolves to number.
Type narrowing
packages/runtime-core/src/apiSetupHelpers.ts
Refines BooleanKey<T> type to add conditional check boolean extends T[K] within the [T[K]] extends [boolean | undefined] branch, ensuring keys are only selected for strictly boolean props rather than boolean-or-undefined combinations.

Sequence Diagram(s)

sequenceDiagram
    participant User as defineProps()
    participant BooleanKey
    participant TypeCheck as Type Resolver
    
    Note over User,TypeCheck: Old Behavior
    User->>BooleanKey: foo?: never
    BooleanKey->>TypeCheck: Check [T[K]] extends [boolean | undefined]
    TypeCheck-->>BooleanKey: false (doesn't match)
    BooleanKey-->>User: Exclude foo
    
    User->>BooleanKey: bar?: boolean
    BooleanKey->>TypeCheck: Check [T[K]] extends [boolean | undefined]
    TypeCheck-->>BooleanKey: true
    BooleanKey-->>User: Include bar (unconditional)
    
    Note over User,TypeCheck: New Behavior
    User->>BooleanKey: foo?: never
    BooleanKey->>TypeCheck: Check [T[K]] extends [boolean | undefined]
    TypeCheck-->>BooleanKey: false
    BooleanKey-->>User: Exclude foo ✓
    
    User->>BooleanKey: bar?: boolean
    BooleanKey->>TypeCheck: Check [T[K]] extends [boolean | undefined]
    TypeCheck-->>BooleanKey: true, then check boolean extends T[K]
    TypeCheck-->>BooleanKey: true
    BooleanKey-->>User: Include bar ✓
    
    User->>BooleanKey: baz?: boolean | undefined
    BooleanKey->>TypeCheck: Check [T[K]] extends [boolean | undefined]
    TypeCheck-->>BooleanKey: true, then check boolean extends T[K]
    TypeCheck-->>BooleanKey: false (undefined in union blocks extension)
    BooleanKey-->>User: Exclude baz ✓
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Key areas requiring attention:
    • Type logic validation: verify that the added boolean extends T[K] check correctly filters out optional-or-undefined and never-typed properties across all conditional type branches
    • Test coverage: confirm the new test case adequately validates the fix for the reported issue and doesn't introduce regressions with edge cases (e.g., boolean | null, strictly required boolean props)
    • TypeScript tuple type behavior: ensure the nested conditional logic with [T[K]] tuple wrapping behaves as intended in both strict and non-strict mode

Suggested labels

scope: types, :hammer: p3-minor-bug

Suggested reviewers

  • johnsoncodehk
  • KazariEX

Poem

🐰 A boolean bounces through the type, so true and bright,
But when undefined creeps in, we narrow with delight—
No never props shall fool us now, with guards in place,
The BooleanKey hops more true through TypeScript's space!

Pre-merge checks and finishing touches

✅ Passed checks (4 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: modifying defineProps types to prevent never props from becoming boolean flags, which aligns with the changeset modifications to BooleanKey type logic.
Linked Issues check ✅ Passed The PR addresses issue #14056 by narrowing BooleanKey type to prevent never props from being incorrectly treated as boolean flags under TypeScript strict mode, matching the stated objective.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the defineProps type behavior for never props; test additions and type modifications directly support the linked issue resolution.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch edison/fix/14056

📜 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 5cf0097 and 0600862.

📒 Files selected for processing (2)
  • packages-private/dts-test/setupHelpers.test-d.ts (1 hunks)
  • packages/runtime-core/src/apiSetupHelpers.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)
  • defineProps (89-94)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test / unit-test-windows
🔇 Additional comments (2)
packages-private/dts-test/setupHelpers.test-d.ts (1)

36-44: LGTM! Test coverage validates the fix.

This test case appropriately validates that props with never type are no longer incorrectly treated as boolean flags. The assertions confirm:

  • foo?: never preserves its type as never | undefined (not converted to boolean)
  • Other props like bar: number remain unaffected
packages/runtime-core/src/apiSetupHelpers.ts (1)

100-106: No issues found - the BooleanKey type change is correct and well-tested.

The git history confirms this change is intentional: commit 0600862 specifically added the nested boolean extends T[K] conditional to prevent never type props from being treated as boolean flags. The commit includes updated test cases that validate this behavior. The existing boolean prop tests (lines 19-34) remain unaffected and verify that boolean and boolean | undefined props continue to work correctly.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Nov 6, 2025

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 103 kB 38.9 kB 35 kB
vue.global.prod.js 161 kB 58.8 kB 52.3 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.9 kB 18.3 kB 16.8 kB
createApp 55 kB 21.4 kB 19.6 kB
createSSRApp 59.3 kB 23.1 kB 21.1 kB
defineCustomElement 60.6 kB 23.1 kB 21.1 kB
overall 69.3 kB 26.6 kB 24.3 kB

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 6, 2025

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@14059

@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@14059

@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@14059

@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@14059

@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@14059

@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@14059

@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@14059

@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@14059

@vue/shared

npm i https://pkg.pr.new/@vue/shared@14059

vue

npm i https://pkg.pr.new/vue@14059

@vue/compat

npm i https://pkg.pr.new/@vue/compat@14059

commit: 0600862

@edison1105 edison1105 requested a review from KazariEX November 6, 2025 03:53
@edison1105 edison1105 added scope: types ready to merge The PR is ready to be merged. labels Nov 6, 2025
Comment on lines 100 to 106
type BooleanKey<T, K extends keyof T = keyof T> = K extends any
? [T[K]] extends [boolean | undefined]
? K
? boolean extends T[K]
? K
: never
: never
: never
Copy link
Member

@KazariEX KazariEX Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type BooleanKey<T, K extends keyof T = keyof T> = K extends any
? [T[K]] extends [boolean | undefined]
? K
? boolean extends T[K]
? K
: never
: never
: never
type BooleanKey<T, K extends keyof T = keyof T> = K extends any
? T[K] extends boolean | undefined
? T[K] extends never | undefined
? never
: K
: never
: never

boolean extends T[K] will cause that true or false is not inferred as boolean keys.

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

Labels

ready to merge The PR is ready to be merged. scope: types

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeScript enables strict mode, and the interface includes an optional never type; defineProps returns the never type.

3 participants