flekschas / svelte-simple-modal

A simple, small, and content-agnostic modal for Svelte v3 and v4
https://svelte.dev/repl/b95ce66b0ef34064a34afc5c0249f313
MIT License
422 stars 30 forks source link

Property 'close' does not exist on type 'unknown' #88

Open KoljaL opened 1 year ago

KoljaL commented 1 year ago

My Login.svelteModal starts like this:

<script lang="ts">
    import { getContext } from 'svelte';
    const { close } = getContext('simple-modal');

    export let title: string;
    export let callbackFCN = (value: boolean) => {};
    ....

    if (login === true) { 
        close();
        callbackFCN(true);
    } else {
        errorMsg = 'wrong password';
    }
</script>

It should close itself, if the login is true, and it does. But in VSCode i got this error for { close } : Property 'close' does not exist on type 'unknown'. ts(2339)

flekschas commented 1 year ago

I supposed the types are not properly defined. Which version of the library are you using?

KoljaL commented 1 year ago

HI flekschas and thanks for the fast reply.

I'm using the current version: "svelte-simple-modal": "^1.4.1"

flekschas commented 1 year ago

Thanks for clarifying which version you're running. I realized that both the open() and close() functions do not have JSDoc type defs, which is why their type is unknown. Let me see if I can fix the issue with sveld (which auto-generates the types for this library)

flekschas commented 1 year ago

Unfortunately, I am not yet sure how to properly type variables that are exposed via setContext but I've opened a ticket with Sveld: https://github.com/carbon-design-system/sveld/issues/103.

In the meantime, I've improved the type definitions a bit so you should at least be able to manually declare the type as follows:

import type { Open, Close } from 'svelte-simple-modal';
const { open, close } = getContext('simple-modal') as { open: Open, close: Close };

I know this is only an interim solution but I hope it helps until I've figured out a better solution.

HasanAboShally commented 1 year ago

@flekschas, thanks for sharing the workaround.

On the line: import type { Open, Close } from 'svelte-simple-modal';

I get the following error:

Module '"svelte-simple-modal"' has no exported member 'Open'. Did you mean to use 'import Open from "svelte-simple-modal"' instead?ts(2614).

Currently the following seems to work:

import type Close from 'svelte-simple-modal'; import type Open from 'svelte-simple-modal';

But now I receive an error on open(Popup, { message: "It's a modal!" });: This expression is not callable. Type 'Modal' has no call signatures.ts(2349)

flekschas commented 1 year ago

Apologies, I had a typo. It should be

import { getContext } from 'svelte';
import type { Context } from 'svelte-simple-modal/types/Modal.svelte';
const { open, close } = getContext('simple-modal') as Context;

I'll see if I can get the Context exported from index.d.ts

flekschas commented 1 year ago

@HasanAboShally The typing should be fixed in v1.5.2 now. The following should not throw an error anymore:

<script lang="ts">
  import { getContext } from 'svelte';
  import { bind } from 'svelte-simple-modal';
  import type { Context } from 'svelte-simple-modal';

  import Popup from './popup.svelte';

  const { open } = getContext('svelte-simple-modal') as Context;

  function openModal() {
    open(bind(Popup, { message: 'It\'s a modal!' }));
  }
</script>

<button on:click={openModal}>Open a modal</button>
LeoDog896 commented 1 year ago

By the way, instead of using as Context, you can use getContext's generics:

<script lang="ts">
  import { getContext } from 'svelte';
  import { bind } from 'svelte-simple-modal';
  import type { Context } from 'svelte-simple-modal';

  import Popup from './popup.svelte';

  const { open } = getContext<Context>('svelte-simple-modal');

  function openModal() {
    open(bind(Popup, { message: 'It\'s a modal!' }));
  }
</script>

<button on:click={openModal}>Open a modal</button>