Search code examples
typescriptsveltesvelte-3svelte-component

Accessing not defined property on svelte component should raise TypeScript type error


When using Svelte with TypeScript, I expected that accessing a property on a component that has not been defined to result in a type error. It results in the property being typed as any instead.

I have this example code at hand:

myComponent.svelte

<script lang="ts">
    export function doSomething(input: string) {
        return input;
    }
</script>

<p>Text</p>

myOtherComponent.svelte

<script lang="ts">
    import MyComponent from './MyComponent.svelte';
    let myComponent: MyComponent;
    function someFunction() {
        const myStringReturn = myComponent.doSomething('some-string'); // myStringReturn is correctly typed as string
        myComponent.somethingNotDefined; // somethingNotDefined is typed as any. Instead, I'd like to see a TypeScript error like: Property somethingNotDefined does not exist on type MyComponent
    }
</script>

<MyComponent bind:this={myComponent}></MyComponent>

In myOtherComponent.svelte myComponent.doSomething is correctly typed. However myComponent.somethingNotDefined is of type any. Instead, I'd like to see a type error raised by TypeScript here.

Is this possible to achieve somehow? Can I add some kind of TypeScript compiler flag to issue an error in this case? Or can I perhaps use a different type for myComponent? I tried using ComponentType<{doSomething: (a: string) => string}>, but that did not work either


Solution

  • I've found the solution. It's pretty simple. Instead of using the MyComponent as a type for myComponent, I can just define it's type as an object: { doSomething: (a: string) => string }

    <script lang="ts">
        import MyComponent from './MyComponent.svelte';
        let myComponent: { doSomething: (a: string) => string };
        function someFunction() {
            const myStringReturn = myComponent.doSomething('some-string'); // myStringReturn is correctly typed as string
            myComponent.somethingNotDefined; // this is now a type error, as expected.
        }
    </script>
    
    <MyComponent bind:this={myComponent}></MyComponent>