Language-tools: [TypeScript] Typing a variable holding a component as value

Created on 26 Aug 2020  ·  6Comments  ·  Source: sveltejs/language-tools

When using TypeScript, it seems impossible to use a component as a type.
For instance, it is not possible to type a store to hold a component instance like so:

import AnyComponent from "./AnyComponent"

const componentStore = writable<SvelteComponent>(null)

$componentStore = AnyComponent

The last line will give the following error:

Type 'typeof \

Maybe it is me that's missed something about how components are typed, but I would like to be able to use that kind of pattern.

Here is a StackOverflow post I opened before writing this issue, where @dummdidumm instructed me to open this issue. I hope that's ok.

Fixed bug

Most helpful comment

Hi there 😄
One thing is that we are missing some properties/methods on our internal definition of our Svelte component class. The other thing is that the typing is wrong, it should be writable<typeof SvelteComponent>, else you are refering to the instance of that component, not the class type.

All 6 comments

Hi there 😄
One thing is that we are missing some properties/methods on our internal definition of our Svelte component class. The other thing is that the typing is wrong, it should be writable<typeof SvelteComponent>, else you are refering to the instance of that component, not the class type.

I have encountered a similar issue.

import type { SvelteComponent } from 'svelte';
import Comp from './Comp.svelte';

const comp: SvelteComponent = Comp; // Type 'typeof SvelteComponentDev' is missing the following properties from type SvelteComponentDev: $set, $on, $destroy ...

v 3.35.0

The question is, why an imported component has a type "typeof SvelteComponentDev" rather than SvelteComponentDev

Because Comp is the class, not the instance of that class.

class Foo {
    bar: string;
}

class Comp extends Foo {}

const comp: Foo = new Comp(); // OK
const compClass1: Foo = Comp; // WRONG
const compClass2: typeof Foo = Comp; // OK

Ahh. Makes sense. Thank you.

Fighting with this for 2 days straight now. I just don't get it:

<script lang="ts">
  import MyComponent from "./MyComponent.svelte";
  let myComponent: typeof MyComponent;
</script>

<MyComponent bind:this={myComponent}/> //Error here
Argument of type 'typeof MyComponent__SvelteComponent_' is not assignable to parameter of type 'MyComponent__SvelteComponent_'.   
Type 'typeof MyComponent__SvelteComponent_' is missing the following properties from type 'MyComponent__SvelteComponent_': $$prop_def, $$events_def, $$slot_def, $on, and 5 more.ts(2345)

What am i doing wrong here? I just want to get that Instance into a variable. 😭

@Alfagun74 the issue you are facing is not the same as others in this thread. What you want is an instance of the class. So you just need:

<script lang="ts">
  import MyComponent from "./MyComponent.svelte";
  let myComponent: MyComponent;
</script>

<MyComponent bind:this={myComponent}/>

Other people want a dynamic component so they need the class itself, a special function.

Was this page helpful?
0 / 5 - 0 ratings