Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/olive-pandas-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: allow using typescript in `customElement.extend` option
2 changes: 2 additions & 0 deletions documentation/docs/07-misc/04-custom-elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 5 additions & 0 deletions packages/svelte/src/compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { test } from '../../assert';
const tick = () => Promise.resolve();

export default test({
async test({ assert, target }) {
target.innerHTML = '<custom-element name="world"></custom-element>';
await tick();
/** @type {any} */
const el = target.querySelector('custom-element');

assert.htmlEqual(
el.shadowRoot.innerHTML,
`
<p>name: world</p>
`
);
assert.equal(el.test, `test`);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<svelte:options customElement={{
tag: "custom-element",
extend: (customClass)=>{
return class extends customClass{
public test: string = "test";
}
},
}}/>

<script lang="ts">
let { name } = $props();
</script>

<p>name: {name}</p>