diff --git a/.changeset/olive-pandas-trade.md b/.changeset/olive-pandas-trade.md
new file mode 100644
index 0000000000..bef36a3075
--- /dev/null
+++ b/.changeset/olive-pandas-trade.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: allow using typescript in `customElement.extend` option
diff --git a/documentation/docs/07-misc/04-custom-elements.md b/documentation/docs/07-misc/04-custom-elements.md
index a8e0c81763..7e6a17b947 100644
--- a/documentation/docs/07-misc/04-custom-elements.md
+++ b/documentation/docs/07-misc/04-custom-elements.md
@@ -114,6 +114,8 @@ When constructing a custom element, you can tailor several aspects by defining `
...
```
+> [!NOTE] While Typescript is supported in the `extend` function, it is subject to limitations: you need to set `lang="ts"` on one of the scripts AND you can only use [erasable syntax](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) in it. They are not processed by script preprocessors.
+
## Caveats and limitations
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:
diff --git a/packages/svelte/src/compiler/index.js b/packages/svelte/src/compiler/index.js
index 42427dd9c4..756a88a824 100644
--- a/packages/svelte/src/compiler/index.js
+++ b/packages/svelte/src/compiler/index.js
@@ -43,6 +43,11 @@ export function compile(source, options) {
instance: parsed.instance && remove_typescript_nodes(parsed.instance),
module: parsed.module && remove_typescript_nodes(parsed.module)
};
+ if (combined_options.customElementOptions?.extend) {
+ combined_options.customElementOptions.extend = remove_typescript_nodes(
+ combined_options.customElementOptions?.extend
+ );
+ }
}
const analysis = analyze_component(parsed, source, combined_options);
diff --git a/packages/svelte/tests/runtime-browser/custom-elements-samples/extend-with-ts/_config.js b/packages/svelte/tests/runtime-browser/custom-elements-samples/extend-with-ts/_config.js
new file mode 100644
index 0000000000..6502a08290
--- /dev/null
+++ b/packages/svelte/tests/runtime-browser/custom-elements-samples/extend-with-ts/_config.js
@@ -0,0 +1,19 @@
+import { test } from '../../assert';
+const tick = () => Promise.resolve();
+
+export default test({
+ async test({ assert, target }) {
+ target.innerHTML = '
name: world
+ ` + ); + assert.equal(el.test, `test`); + } +}); diff --git a/packages/svelte/tests/runtime-browser/custom-elements-samples/extend-with-ts/main.svelte b/packages/svelte/tests/runtime-browser/custom-elements-samples/extend-with-ts/main.svelte new file mode 100644 index 0000000000..ddd2d4b61a --- /dev/null +++ b/packages/svelte/tests/runtime-browser/custom-elements-samples/extend-with-ts/main.svelte @@ -0,0 +1,14 @@ +name: {name}
\ No newline at end of file