sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
76.8k stars 3.98k forks source link

Svelte 5: `ComponentType` is still a constructor #11472

Open r-thomson opened 1 week ago

r-thomson commented 1 week ago

Describe the bug

In Svelte 5, components are no longer classes. However, the ComponentType type is still defined as a class constructor, not a function. This leads to situations where perfectly correct code is flagged as incorrect by the type checker.

Reproduction

Here is a simple example of trying to “wrap” a component:

import MyComponent from "./MyComponent.svelte";
const WrappedComponent = (anchor, props) => MyComponent(anchor, { ...props });

This code generates the TypeScript error Value of type 'typeof MyComponent__SvelteComponent_' is not callable. Did you mean to include 'new'?.

Logs

No response

System Info

System:
    OS: macOS 14.4.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 111.14 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.0.0 - /opt/homebrew/bin/node
    Yarn: 1.22.22 - /opt/homebrew/bin/yarn
    npm: 10.5.1 - /opt/homebrew/bin/npm
  Browsers:
    Safari: 17.4.1
  npmPackages:
    svelte: ^5.0.0-next.123 => 5.0.0-next.123

Severity

annoyance

dummdidumm commented 1 week ago

The real shape of components is deliberately hidden. Doing something like this is prone to break because it's relying on private API. What is the use case for wrapping the component? Wondering if a dedicated API should be introduced for that instead.

paoloricciuti commented 1 week ago

Wondering if a dedicated API should be introduced for that instead.

That would be cool for "higher order components". For example I created a dialog component that uses a bit of Inline JS to be available before the bundle loads (for progressive enhancement). However this requires having the same Id of the trigger. Currently you have to remember to pass the same id. With such API I could create a create dialog function that return the trigger and the dialog while also specifying the id prop by himself.

r-thomson commented 1 week ago

The real shape of components is deliberately hidden. Doing something like this is prone to break because it's relying on private API.

Maybe this is the case starting in Svelte 5, but in Svelte 4 this API seems to be reasonably well documented.

What is the use case for wrapping the component? Wondering if a dedicated API should be introduced for that instead.

Here’s my actual use case: Svelte 4, Svelte 5 (gross hack version)