feat: add customNamespaces option for custom namespaced attributes#3057
Closed
khromov wants to merge 1 commit into
Closed
feat: add customNamespaces option for custom namespaced attributes#3057khromov wants to merge 1 commit into
khromov wants to merge 1 commit into
Conversation
…m type validation Frameworks built on top of Svelte attach custom namespaced attributes (e.g. <Counter mochi:hydrate />) which previously caused "Type 'true' is not assignable to type 'never'" errors. Adds a configurable, opt-in customNamespaces option: - svelte2tsx: new customNamespaces?: string[] option, honored in both the element (addAttribute) and component (addProp) branches via the existing __sveltets_2_empty wrapper so value expressions stay type-checked. - svelte-check (CLI) and language server (editor) both read it from svelte.config.js, keeping CLI and editor in lockstep. Includes svelte2tsx fixtures, language-server diagnostics tests, README docs, and a changeset.
🦋 Changeset detectedLatest commit: d77082b The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Member
|
Since we want to get rid of svelte.config.js at some point this would go the wrong way for this goal. |
Author
|
@dummdidumm Makes sense, how about this approach? #3060 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Frameworks built on top of Svelte attach custom namespaced attributes to elements and components to carry framework-level metadata, e.g. an SSR/islands framework:
At runtime Svelte passes these through, but at type-check time
svelte2tsxemits the attribute as a real prop/attribute, so TypeScript reports a hard error:There was no supported way to exempt these attributes. Downstream projects monkey-patch the bundled
svelte-checkoutput (a hard-coded carve-out inhandleAttribute), which breaks on every version bump, hard-codes a single prefix, and only covers the component branch.Solution
An opt-in, declarative
customNamespacesoption, configured once insvelte.config.jsand honored by both the CLI (svelte-check) and the editor (language server):An entry
'mochi'matches an attribute named exactlymochior any attribute starting withmochi:(matching rule:name === ns || name.startsWith(ns + ':'); a trailing:is normalized away). Matching attributes reuse the existing__sveltets_2_empty({ ... })wrapper thatdata-*already uses, in both the element (addAttribute) and component (addProp) branches — so the attribute name is exempt from prop/attribute validation while any value expression stays type-checked (mochi:defer={someVar}still errors ifsomeVaris undefined).Why this shape
string[]mirrors the existingdata-/--handling, is trivial to serialize/validate/document, and works everywhere config is consumed. A predicate could be added later as a superset.customNamespacesover a generic prefix match — real-world cases are colon-delimited namespaces; "namespace" matches Svelte's own vocabulary (bind:,on:,use:).svelte.config.js— one source of truth keeps CLI and editor in lockstep; a CLI-only fix would still leave red squiggles in the IDE.Changes
svelte2tsx: newcustomNamespaces?: string[]option (normalized), threadedsvelte2tsx → convertHtmlxToJsx → handleAttribute; matching branch added to both attribute paths.svelte-language-server: readscustomNamespacesfromsvelte.config.js(SvelteConfig) and passes it through the document snapshot path.svelte-check: reads it from the loaded config in the incremental emit path. (The non-incremental path already flows through the language server.)Tests
svelte2tsxfixtures:custom-namespaces(with option; covers component + element, value-less, expression value, and bare-namespace match) andcustom-namespaces-disabled(control — confirms unwrapped emit, i.e. no global behavior change).language-serverdiagnostics fixtures: enabled → 0 errors; value-checked → onlyCannot find name 'typoVar'(proves expressions still checked); disabled → exactlyType 'true' is not assignable to type 'never'.Docs / changeset
svelte-checkREADME: new "Custom attribute namespaces" section, cross-linking--compiler-warnings "attribute_illegal_colon:ignore"(frameworks typically need both: the warning suppressed and the namespace registered).minorchangeset forsvelte2tsx,svelte-check,svelte-language-server.Notes / open questions for maintainers
--custom-namespaces mochi,fooconvenience flag was intentionally left out (config-first gives editor parity for free; threading a CLI value into the per-file config loader is invasive). Happy to add it as a follow-up if desired.Out of scope
attribute_illegal_colonwarning (already configurable via--compiler-warnings).