maciekgrzybek / svelte-inview

A Svelte action that monitors an element enters or leaves the viewport.🔥
MIT License
749 stars 23 forks source link

Another Typescript issue #37

Closed brev closed 1 year ago

brev commented 1 year ago

Hi, thanks for the great code. It is working great.

However, I'm still getting Typescript errors, despite trying everything mentioned in the docs and other issues:

Type '{ onleave: ({ detail }: CustomEvent<ObserverEventDetails>) => void; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.
  Property 'onleave' does not exist on type 'HTMLProps<HTMLDivElement>'.

My code is basically this:

<script lang="ts">
  import type { ObserverEventDetails } from 'svelte-inview'
  import { inview } from 'svelte-inview'

  let state = false

  const leaveHandler = ({ detail }: CustomEvent<ObserverEventDetails>) => {
    if (detail.scrollDirection.vertical === 'up') state = true
  }
</script>

<div use:inview on:leave={leaveHandler}>
  Hello {state}
</div>

I notice in your Typescript definitions that "on:leave" is set for HTMLAttributes. But I'm not sure how this ends up as "onleave" for HTMLProps.

Any ideas? Not a showstopper, just an annoyance. Thanks for any help.

maciekgrzybek commented 1 year ago

Hey, @brev thanks for the issue :) Can you give me some more details about the other packages you're using? I mean svelte-related :)

hmajid2301 commented 1 year ago

I'm noticing a similar issue with on:enter

    use:inview={{}}
    on:enter={async () => {
        if (collection.moreBookmarks) {
            page += 1;
            await getBookmarks();
            console.log("IN VIEW", page);
        }
    }} />

Here is a list of the packages i'm using: https://gitlab.com/bookmarkey/gui/-/blob/main/package.json

Link to code: https://gitlab.com/bookmarkey/gui/-/blob/main/src/routes/my/collections/%5Bid%5D/%2Bpage.svelte#L48-55

Full error message:

src/routes/my/collections/[id]/+page.svelte:46:17
Error: Type '{ onenter: ({ detail }: { detail: any; }) => void; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.
  Property 'onenter' does not exist on type 'HTMLProps<HTMLDivElement>'. (ts)
maciekgrzybek commented 1 year ago

Thanks for the details @hmajid2301 :) I think I know what it is. Can you downgrade svelte-inview to version 3.0.1 ? In version 3.0.2 I've introduced new types as svelte-check (one of the dependencies) has changed the typings. If that will help, it means that you'll need to update the package which has a dependency on svelte-check

hmajid2301 commented 1 year ago

Thank you @maciekgrzybek for your swift reply. That is very helpful.

I decided to upgrade svelte-check to version 3 and now I'm getting a new error. The default on:change in my input is conflicting with the on:change in the package.

src/lib/components/atoms/Input.svelte:16:6
Error: Argument of type '{ "on:input": undefined; "on:change": undefined; "on:blur": undefined; id: string; accept: string | null; autocomplete: string | null; name: string; required: boolean; type: string; placeholder: string | null; value: string | undefined; disabled: boolean; class: string; }' is not assignable to parameter of type 'HTMLProps<"input", HTMLAttributes<any>>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
  Type '{ "on:input": undefined; "on:change": undefined; "on:blur": undefined; id: string; accept: string | null; autocomplete: string | null; name: string; required: boolean; type: string; placeholder: string | null; value: string | undefined; disabled: boolean; class: string; }' is not assignable to type 'HTMLAttributes<any>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
    Types of property ''on:change'' are incompatible.
      Type 'undefined' is not assignable to type '(event: CustomEvent<ObserverEventDetails>) => void'. (ts)

Any ideas what I can do to fix this i.e. get it to use the normal on:change. Thanks again!

maciekgrzybek commented 1 year ago

@hmajid2301 this is weird... I'll take a look this evening and will let you know :)

maciekgrzybek commented 1 year ago

Ok so I've managed to track down the issue. Like you've mentioned, the names of events were conflicting with each other. I decided to prepare version 4 of the package with semi-breaking changes :) From new readme:

Version 4 introduces new names for events. Before they were 'change' | 'leave' | 'enter' | 'init'. In version 4 they're changed to 'inview_change' | 'inview_leave' | 'inview_enter' | 'inview_init'.

This change was needed to satisfy Typescript, as the package was messing up the default types coming from svelte typings. To ensure backward compatibility, the original events names will still work for some time, but they won't be properly recognized by Typescript. To sum up, this will still work, but TS won't be happy about it:

on:change={(event) => {
  const { inView, entry, scrollDirection, observer, node} = event.detail;
  isInView = inView;
}}

To make sure it works properly and satisfy TS you'll need to change it to this:

on:inview_change={(event) => {
  const { inView, entry, scrollDirection, observer, node} = event.detail;
  isInView = inView;
}}

I've tested it locally + in unit tests and it works as expected, but I'd appreciate it if you could test it locally in your project? :) I tried it, but couldn't even start it, unfortunately :( If you can install svelte-inview package from the GH branch instead of npm with this command -> pnpm install 'https://github.com/maciekgrzybek/svelte-inview.git#v-4.0.0' and check if it works with both old events names and new ones. Thanks in advance and let me know if you need more assistance :)

hmajid2301 commented 1 year ago

I've tested it locally + in unit tests and it works as expected, but I'd appreciate it if you could test it locally in your project? :) I tried it, but couldn't even start it, unfortunately :(

Sign the docs weren't very good XD. I will fix that on my side.

It looks like I'm getting same issue: https://gitlab.com/bookmarkey/gui/-/jobs/3899707240

MR: https://gitlab.com/bookmarkey/gui/-/merge_requests/125

Thanks

maciekgrzybek commented 1 year ago

But you haven't update the svelte-check in this MR?

hmajid2301 commented 1 year ago

I was already using svelte-check v3. But i've updated to latest version in MR now.

maciekgrzybek commented 1 year ago

Hmmm 🤔 Are you sure that gitlab ci doesn't keep any cache? What about locally? Are you seeing that error your Code Editor?

hmajid2301 commented 1 year ago

Same issue locally here is my command + output

task check
task: [check] pnpm run check

> bookmarkey-gui@0.0.1 check /home/haseeb/projects/bookmarkey/gui
> svelte-kit sync && svelte-check --tsconfig ./tsconfig.json

====================================
Loading svelte-check in workspace: /home/haseeb/projects/bookmarkey/gui
Getting Svelte diagnostics...

/home/haseeb/projects/bookmarkey/gui/src/lib/components/atoms/Input.svelte:16:6
Error: Argument of type '{ "on:input": undefined; "on:change": undefined; "on:blur": undefined; id: string; accept: string | null; autocomplete: string | null; name: string; required: boolean; type: string; placeholder: string | null; value: string | undefined; disabled: boolean; class: string; }' is not assignable to parameter of type 'HTMLProps<"input", HTMLAttributes<any>>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
  Type '{ "on:input": undefined; "on:change": undefined; "on:blur": undefined; id: string; accept: string | null; autocomplete: string | null; name: string; required: boolean; type: string; placeholder: string | null; value: string | undefined; disabled: boolean; class: string; }' is not assignable to type 'HTMLAttributes<any>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
    Types of property ''on:change'' are incompatible.
      Type 'undefined' is not assignable to type '(event: CustomEvent<ObserverEventDetails>) => void'. (ts)

<input
        bind:this={ref}
        on:input
        on:change
        on:blur
        id={name}
        {accept}
        {autocomplete}
        {name}
        {required}
        {type}
        {placeholder}
        {value}
        {disabled}
        class={`${inputClass} ${extraClasses}`} />

====================================
svelte-check found 1 error and 0 warnings
 ELIFECYCLE  Command failed with exit code 1.
task: Failed to run task "check": exit status 1

Where my check scripts looks like this:

"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",

Yes vscode is also showing the error:

image

maciekgrzybek commented 1 year ago

Ok it's really weird, I just downloaded your project, uninstalled svelte-inview with pnpm uninstall and then install the new version with pnpm install 'https://github.com/maciekgrzybek/svelte-inview.git#v-4.0.0' and it works like a charm. No errors in the Input file. Are you sure you've got the correct version installed?

Screenshot 2023-03-11 at 10 29 14
hmajid2301 commented 1 year ago

That fixed it; but not i'm getting another issue. It seems on:enter is not valid ?

task: [check] pnpm run check

> bookmarkey-gui@0.0.1 check /home/haseeb/projects/bookmarkey/gui
> svelte-kit sync && svelte-check --tsconfig ./tsconfig.json

====================================
Loading svelte-check in workspace: /home/haseeb/projects/bookmarkey/gui
Getting Svelte diagnostics...

/home/haseeb/projects/bookmarkey/gui/src/routes/my/collections/[id]/+page.svelte:49:5
Error: Argument of type '{ "on:enter": () => Promise<void>; }' is not assignable to parameter of type 'Omit<Omit<HTMLAttributes<HTMLDivElement>, "data-sveltekit-noscroll" | "data-sveltekit-preload-code" | "data-sveltekit-preload-data" | ... 74 more ... | "on:pressmove"> & EventsWithColon<...>, keyof HTMLAttributes<...>> & HTMLAttributes<...>'.
  Object literal may only specify known properties, and '"on:enter"' does not exist in type 'Omit<Omit<HTMLAttributes<HTMLDivElement>, "data-sveltekit-noscroll" | "data-sveltekit-preload-code" | "data-sveltekit-preload-data" | ... 74 more ... | "on:pressmove"> & EventsWithColon<...>, keyof HTMLAttributes<...>> & HTMLAttributes<...>'. (ts)
        use:inview={{}}
        on:enter={async () => {
                console.log("HELLO");
                if (collection.moreBookmarks) {
                        console.log("HELLO");
                        page += 1;
                        await getBookmarks();
                }
        }} />
maciekgrzybek commented 1 year ago

Yep, that's expected. In the documentation I'v added info about it :) To make sure there are no conflicts, I had to add prefixes to the methods so on:enter becomes on:inview_enter. To keep the backward compatibility I left the original ones as well, but the TS will complain.

hmajid2301 commented 1 year ago

Thanks that seems to have fixed it for me!

maciekgrzybek commented 1 year ago

@brev can you confirm that it works fine for you as well now? I've just released v4

brev commented 1 year ago

Thanks for the hard work @maciekgrzybek and @hmajid2301.

I've upgraded to 4.0.0, and changed my handler names from enter/leave to inview_enter/inview_leave. It's still functioning correctly. svelte-check is passing with no errors.

However, my editor is still complaining, basically the same as before:

Type '{
  oninview_leave: ({ detail }: CustomEvent<ObserverEventDetails>) => void;
  oninview_enter: ({ detail }: CustomEvent<ObserverEventDetails>) => void;
}' is not assignable to type 'HTMLProps<HTMLDivElement>'.
  Property 'oninview_leave' does not exist on type 'HTMLProps<HTMLDivElement>'.

Here is a list of my dependencies: https://gist.github.com/brev/236a0698648af37e99e06680efdd574f

Grep results from my node_modules for: HTMLProps:

svelte-check@3.1.4/node_modules/svelte-check/dist/src/svelte-jsx.d.ts

Grep results from my node_modules for: HTMLDivElement:

jsdom@21.1.1/node_modules/jsdom/lib/jsdom/living/helpers/create-element.js
jsdom@21.1.1/node_modules/jsdom/lib/jsdom/living/interfaces.js
jsdom@21.1.1/node_modules/jsdom/lib/jsdom/living/nodes/HTMLDivElement-impl.js
jsdom@21.1.1/node_modules/jsdom/lib/jsdom/living/generated/HTMLDivElement.js
svelte@3.55.1/node_modules/svelte/elements/index.d.ts
svelte@3.55.1/node_modules/svelte/compiler.js.map
svelte@3.55.1/node_modules/svelte/compiler.js
svelte@3.55.1/node_modules/svelte/compiler.mjs
svelte@3.55.1/node_modules/svelte/compiler.mjs.map
svelte@3.55.1/node_modules/svelte/types/runtime/action/index.d.ts
svelte-check@3.1.4_gqx7lw3sljhsd4bstor5m2aa2u/node_modules/svelte-check/dist/src/svelte-jsx.d.ts
@ts-morph+common@0.18.1/node_modules/@ts-morph/common/dist/ts-morph-common.js
rollup@3.19.1/node_modules/rollup/dist/shared/rollup.js
rollup@3.19.1/node_modules/rollup/dist/es/shared/node-entry.js
globals@13.20.0/node_modules/globals/globals.json
mdn-data@2.0.28/node_modules/mdn-data/api/inheritance.json
svelte-check@3.1.4_luph556zpodi3vqhnlezpo6clm/node_modules/svelte-check/dist/src/svelte-jsx.d.ts
@typescript-eslint+scope-manager@5.55.0/node_modules/@typescript-eslint/scope-manager/dist/lib/dom.js
svelte@3.57.0/node_modules/svelte/compiler.js.map
svelte@3.57.0/node_modules/svelte/elements/index.d.ts
svelte@3.57.0/node_modules/svelte/compiler.js
svelte@3.57.0/node_modules/svelte/compiler.mjs
svelte@3.57.0/node_modules/svelte/compiler.mjs.map
svelte@3.57.0/node_modules/svelte/types/runtime/action/index.d.ts
vitest@0.29.3_jsdom@21.1.1/node_modules/vitest/dist/chunk-env-node.affdd278.js
typescript@4.9.5/node_modules/typescript/lib/lib.dom.d.ts
mdn-data@2.0.30/node_modules/mdn-data/api/inheritance.json
mdn-data@2.0.14/node_modules/mdn-data/api/inheritance.json
typescript@5.0.2/node_modules/typescript/lib/lib.dom.d.ts

thanks.

Spenhouet commented 1 year ago

Hi, I updated to v4 and changed it to the new event handlers and my IDE started complaining. Only thing that helped resolve that was restarting the IDE. All good now.

maciekgrzybek commented 1 year ago

@brev can you also try restarting the editor? CMD+SHIFT+P and Svelte: Restart Language Server

brev commented 1 year ago

Must be a problem with my own editor setup, since svelte-check and tsc --noEmit both pass, and everything is working great. Thanks for the help!