Skip to content

Conversation

unrevised6419
Copy link
Contributor

@unrevised6419 unrevised6419 commented Jan 22, 2025

close #6068

Allow TypeScript projects that have exactOptionalPropertyTypes option enabled to be able to pass explicit props with a value of undefined

https://www.typescriptlang.org/tsconfig/#exactOptionalPropertyTypes

Let's take for example React:

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b30cd2bf71cdef25085038b4a556211c23c16489/types/react/index.d.ts#L3446-L3729

Checklist:

  • Ensure no any | undefined
  • Ensure no undefined | undefined
  • Run format after review

I advise reviewing one commit at a time.

  • In the first commit, I change all multiline unions to single-line unions to make it easier to review changes (same line diff).
  • The second commit adds undefined.
  • The third one formats the file back.
Images

"exactOptionalPropertyTypes": false

image

"exactOptionalPropertyTypes": true

image image

"exactOptionalPropertyTypes": true and fixed src?: string | undefined

image image

Related:

Links:

Summary by CodeRabbit

  • Refactor
    • Updated public JSX/HTML/SVG/ARIA attribute typings so all optional properties explicitly allow undefined. This standardizes attribute behavior across elements, improves type clarity for consumers, and preserves existing runtime behavior.

Copy link

github-actions bot commented Feb 6, 2025

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 100 kB 38 kB 34.3 kB
vue.global.prod.js 158 kB 57.8 kB 51.5 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.4 kB 18.2 kB 16.6 kB
createApp 54.3 kB 21.2 kB 19.3 kB
createSSRApp 58.5 kB 22.9 kB 20.9 kB
defineCustomElement 59.2 kB 22.8 kB 20.7 kB
overall 68.4 kB 26.3 kB 24 kB

Copy link

pkg-pr-new bot commented Feb 6, 2025

Open in Stackblitz

@vue/compiler-ssr

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

@vue/compiler-core

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

@vue/reactivity

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

@vue/runtime-core

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

@vue/compiler-dom

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

@vue/runtime-dom

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

@vue/compiler-sfc

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

@vue/server-renderer

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

@vue/shared

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

vue

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

@vue/compat

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

commit: 0dc9169

@edison1105 edison1105 added ready to merge The PR is ready to be merged. scope: types 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Feb 6, 2025
@edison1105 edison1105 requested a review from jh-leong February 6, 2025 01:01
@edison1105 edison1105 changed the title fix(runtime-dom): add undefined to optional properties fix(jsx): add undefined to optional properties Feb 6, 2025
@jh-leong
Copy link
Member

jh-leong commented Feb 6, 2025

LGTM

Copy link

coderabbitai bot commented May 15, 2025

Walkthrough

The PR updates TypeScript JSX interfaces in packages/runtime-dom/src/jsx.ts, adding | undefined to all optional properties across ARIA, HTML, SVG, element-specific attribute interfaces, and reserved props. Changes are type-only and do not modify runtime behavior.

Changes

Cohort / File(s) Change Summary
JSX attribute interfaces
packages/runtime-dom/src/jsx.ts
Added `

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Add ` undefinedto all optional properties in JSX, HTML, SVG, ARIA, and reserved prop interfaces to support TypeScript's--exactOptionalPropertyTypes (#6068`)

Suggested reviewers

  • KazariEX

Poem

"I nibbled types with careful paws,
adding | undefined for TypeScript's laws.
ARIA, SVG, HTML — all neat and spry,
now vue-tsc passes — hop, hop, hi! 🥕"

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/runtime-dom/src/jsx.ts (1)

1-8: Nitpick: Document the exactOptionalPropertyTypes rationale
Consider enhancing the file header with a brief note explaining that these type changes support TypeScript’s --exactOptionalPropertyTypes compiler option and reference issue #6068 for context.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between d0253a0 and 5372774.

📒 Files selected for processing (1)
  • packages/runtime-dom/src/jsx.ts (9 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/runtime-dom/src/jsx.ts (1)
packages/runtime-core/src/vnode.ts (1)
  • VNodeRef (86-92)
🔇 Additional comments (6)
packages/runtime-dom/src/jsx.ts (6)

49-266: ARIA Attributes: Explicitly include undefined
All attributes in AriaAttributes now correctly include | undefined, satisfying --exactOptionalPropertyTypes requirements. This change aligns with React’s patterns and improves type safety.


277-349: Standard HTMLAttributes: Add | undefined for optional props
The core HTMLAttributes interface has been updated so that innerHTML, style, and all standard HTML props explicitly allow undefined. This ensures JSX consumers can pass undefined without type errors under strict optional property settings.


362-385: Anchor & Area HTML Attributes: Explicit undefined
Both AnchorHTMLAttributes and AreaHTMLAttributes have had their optional props (href, rel, etc.) updated to include | undefined. This is consistent with the PR goal and does not affect runtime behavior.


541-584: InputHTMLAttributes: Include | undefined across input props
The InputHTMLAttributes interface now explicitly adds | undefined to every optional field (accept, checked, placeholder, etc.). This ensures compatibility with stricter TS settings when passing undefined to inputs.


835-862: SVGAttributes: Explicitly allow undefined on SVG props
All SVG-specific props (color, height, width, role, tabindex, etc.) now include | undefined, matching HTML and ARIA interfaces. Good coverage for strict optional types.


1425-1430: ReservedProps: Add | undefined to key/ref props
The ReservedProps type (key, ref, ref_for, ref_key) now explicitly allows undefined, aligning with the rest of the JSX prop types.

@unrevised6419 unrevised6419 force-pushed the fix/runtime-dom-optional branch from e3d3d94 to bf55e8a Compare June 17, 2025 10:01
@unrevised6419
Copy link
Contributor Author

unrevised6419 commented Aug 9, 2025

Note: In TypeScript v5.9, the tsc --init command defaults to "exactOptionalPropertyTypes": true

@unrevised6419
Copy link
Contributor Author

unrevised6419 commented Sep 1, 2025

@edison1105 edison1105 changed the title fix(jsx): add undefined to optional properties types(jsx): add undefined to optional properties Sep 2, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/runtime-dom/src/jsx.ts (4)

268-276: style includes undefined already via StyleValue (minor redundancy)

StyleValue already allows undefined; keeping “| undefined” is harmless but redundant. If you prefer minimal unions, you can drop it.

-  style?: StyleValue | undefined
+  style?: StyleValue

Same applies to SVGAttributes.style below.

Also applies to: 281-282


835-844: SVG: minor nit on style; crossOrigin union looks fine

  • style?: StyleValue | undefined is redundant like HTML (optional).
  • crossOrigin union matches common usage.
-  style?: StyleValue | undefined
+  style?: StyleValue

Also applies to: 858-862


277-349: Optional: add a CI canary to lock behavior under exactOptionalPropertyTypes

Add a tiny TSX compile check with exactOptionalPropertyTypes: true that sets several attributes explicitly to undefined (ref, key, aria-*, href, input props). This prevents regressions.

I can draft a minimal sample + tsconfig for a CI tsc step.

Also applies to: 541-584


49-266: No accidental any | undefined or undefined | undefined patterns found
Refine the “missing | undefined” check to only target quoted ARIA props
Run, for example:

rg -nP "^\s+'aria-[^']+'\?:\s+(?!.*\|\s*undefined\b)(?!any\b)" packages/runtime-dom/src/jsx.ts

to catch any ARIA attributes that lack | undefined without pulling in the element-to-interface mappings.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bf55e8a and 34868ab.

📒 Files selected for processing (1)
  • packages/runtime-dom/src/jsx.ts (9 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/runtime-dom/src/jsx.ts (1)
packages/runtime-core/src/vnode.ts (1)
  • VNodeRef (86-92)
🔇 Additional comments (8)
packages/runtime-dom/src/jsx.ts (8)

49-266: Correct application of exactOptionalPropertyTypes across ARIA attributes

Adding “| undefined” to optional ARIA props looks complete and consistent (including mixed/Booleanish and literal unions). No functional concerns.


278-349: HTMLAttributes now permit explicit undefined (as intended)

innerHTML, role, inputmode, hidden, inert, etc., correctly accept explicit undefined. Matches React DT patterns.


362-372: Anchor/Area/Button attribute unions look correct

href/referrerpolicy/target/value unions mirror platform expectations and allow explicit undefined. Good.

Also applies to: 374-385, 389-410


541-584: InputHTMLAttributes: coverage and edge cases look good

Key spots (capture, checked with Set support, indeterminate, enterKeyHint, type, numeric bounds) correctly include undefined. Good catch on Set for multi-checkbox v-model.


755-771: Textarea value allows null and undefined (good)

This aligns with DOM behavior and exactOptionalPropertyTypes needs.


863-1120: Broad SVG attribute sweep appears thorough

Large set of attributes now permit explicit undefined; enums and Numberish usage are consistent. No obvious gaps spotted.


1122-1298: IntrinsicElementAttributes unchanged except types—OK

No structural changes beyond underlying attribute types. Looks good.


1425-1430: ReservedProps now accept explicit undefined (important for TSX “condition ? ref : undefined”)

This avoids friction under exactOptionalPropertyTypes. Good change.

@edison1105 edison1105 merged commit 842a392 into vuejs:main Sep 2, 2025
6 checks passed
@unrevised6419 unrevised6419 deleted the fix/runtime-dom-optional branch September 2, 2025 11:49
@unrevised6419
Copy link
Contributor Author

Thanks a lot @jh-leong 🥳 🎉 🎁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 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.

Missing support in @vue/runtime-dom for TypeScript's --exactOptionalPropertyTypes option
3 participants