fix: allow using typescript in `customElement.extend` option (#16001)

Closes #15372

---------

Co-authored-by: Dominik G. <dominik.goepel@gmx.de>
pull/16006/head
Paolo Ricciuti 3 months ago committed by GitHub
parent add0c6a987
commit fbb6444fd8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: allow using typescript in `customElement.extend` option

@ -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:

@ -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);

@ -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`);
}
});

@ -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>
Loading…
Cancel
Save