Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render function giving typescript errror when passed a typescript component #194

Closed
theweekendgeek opened this issue Jun 1, 2022 · 14 comments
Assignees
Labels
bug Something isn't working

Comments

@theweekendgeek
Copy link

theweekendgeek commented Jun 1, 2022

I am trying to set up svelte-testing-library together with svelte kit and typescript. I followed the documentation, including the instructions for svelte-jester.
However, when I write a test, i get an error when I pass the imported component to the render function.

The error is TS2769: No overload matches this call.

From what I can see the render function accepts a SvelteComponentTyped<any, any, any> as its first argument.
The imported component, however, is of type typeof SvelteComponentDev. (I added the whole message below)
The error can be seen when executing the test script or already the editor (I tried in vscode and webstorm).

No overload matches this call.
  Overload 1 of 3, '(component: SvelteComponentTyped<any, any, any>, componentOptions?: SvelteComponentOptions<any> | undefined, renderOptions?: Omit<RenderOptions<typeof import("/home/marcus/dev/test/node_modules/@testing-library/dom/types/queries")>, "queries"> | undefined): RenderResult<...>', gave the following error.
    Argument of type 'typeof default' is not assignable to parameter of type 'SvelteComponentTyped<any, any, any>'.
      Type 'typeof default' is missing the following properties from type 'SvelteComponentTyped<any, any, any>': $set, $on, $destroy, $$prop_def, and 5 more.
  Overload 2 of 3, '(component: SvelteComponentTyped<any, any, any>, componentOptions?: SvelteComponentOptions<any> | undefined, renderOptions?: RenderOptions<Queries> | undefined): RenderResult<...>', gave the following error.
    Argument of type 'typeof default' is not assignable to parameter of type 'SvelteComponentTyped<any, any, any>'.
  Overload 3 of 3, '(component: SvelteComponentTyped<any, any, any>, componentOptions?: SvelteComponentOptions<any> | undefined, renderOptions?: Omit<RenderOptions<typeof import("/home/marcus/dev/test/node_modules/@testing-library/dom/types/queries")>, "queries"> | undefined): RenderResult<...>', gave the following error.
    Argument of type 'typeof default' is not assignable to parameter of type 'SvelteComponentTyped<any, any, any>'.ts(2769)
comp.test.ts(13, 31): Did you mean to use 'new' with this expression?
comp.test.ts(13, 31): Did you mean to use 'new' with this expression?
comp.test.ts(13, 31): Did you mean to use 'new' with this expression?

I also created a repo for reproduction. It is basically just a new svelte kit project with typescript and then I followed the instructions to set up svelte-testing-library: https://github.com/theweekendgeek/svelte-testing-library-ts-example

edit: I had another quick look after seeing #181. I compared the repos and saw that they were using svelte-testing-library 3.0.3. After installing the exact version number it the typeerror is gone. but when running the tests I get another error:

> jest src

node:internal/errors:465
    ErrorCaptureStackTrace(err);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of SyntaxError
    at new NodeError (node:internal/errors:372:5)
    at _write (node:internal/streams/writable:312:13)
    at Socket.Writable.write (node:internal/streams/writable:334:10)
    at file:///home/marcus/dev/rpg-emu-front/node_modules/svelte-jester/dist/preprocess.js:21:32 {
  code: 'ERR_INVALID_ARG_TYPE'
}
 1: 0xb09c10 node::Abort() [node]
 2: 0xb0c15d  [node]
 3: 0xd552fe  [node]
 4: 0xd5671f v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
 5: 0x15f2179  [node]
 FAIL  src/components/Button.test.ts
  ● Test suite failed to run

    Command failed: node --unhandled-rejections=strict --abort-on-uncaught-exception "/home/marcus/dev/rpg-emu-front/node_modules/svelte-jester/dist/preprocess.js"
    node:internal/errors:465
        ErrorCaptureStackTrace(err);
        ^

    TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of SyntaxError
        at new NodeError (node:internal/errors:372:5)
        at _write (node:internal/streams/writable:312:13)
        at Socket.Writable.write (node:internal/streams/writable:334:10)
        at file:///home/marcus/dev/rpg-emu-front/node_modules/svelte-jester/dist/preprocess.js:21:32 {
      code: 'ERR_INVALID_ARG_TYPE'
    }
     1: 0xb09c10 node::Abort() [node]
     2: 0xb0c15d  [node]
     3: 0xd552fe  [node]
     4: 0xd5671f v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
     5: 0x15f2179  [node]


      at file:/home/marcus/dev/rpg-emu-front/node_modules/svelte-jester/dist/preprocess.js:21:32 {
        code: 'ERR_INVALID_ARG_TYPE'
      }
       1: 0xb09c10 node::Abort() [node]
       2: 0xb0c15d  [node]
       3: 0xd552fe  [node]
       4: 0xd5671f v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
       5: 0x15f2179  [node]
      at Object.processSync [as process] (node_modules/svelte-jester/dist/transformer.cjs:115:42)
      at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:619:31)
      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:765:40)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:822:19)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.322 s
Ran all test suites matching /src/i

another edit after comparing again with the referenced repo from #181 I think I was able to resolve the issue. I had to change the extension of the svelte.config.js to .mjs and then point the jest config file to it.

@yanick
Copy link
Collaborator

yanick commented Jun 1, 2022

Was able to reproduce using your example, thanks! I'll try to have a look at it this week.

And for what it's worth: it's all working if you load your shotgun with anys and fire wildly at the tests. :-)

@yanick yanick self-assigned this Jun 1, 2022
@yanick yanick added the bug Something isn't working label Jun 1, 2022
@ITenthusiasm
Copy link

ITenthusiasm commented Jun 1, 2022

Found a couple random things. Leaving this be for now.

Looking at pure.js, it's looking like the render function expects the physical class, not an instance of the class. That being the case, the argument for the component must be typeof Class, not Class. (You can see this by playing in a TypeScript playground.) There appears to have been a regression in 167b46b where the necessary typeof was removed.

When I edit the types/index.d.ts file and put typeof back, I get the following error:

No overload matches this call.
  Overload 1 of 3, '(component: typeof SvelteComponentTyped, componentOptions?: SvelteComponentOptions<any> | undefined, renderOptions?: Omit<RenderOptions<typeof import("C:/Users/thoma/repos/personal-budgeting/node_modules/@testing-library/dom/types/queries")>, "queries"> | undefined): RenderResult<...>', gave the following error.
    Argument of type 'typeof Select__SvelteComponent_' is not assignable to parameter of type 'typeof SvelteComponentTyped'.
      Types of construct signatures are incompatible.
        Type 'new (options: Svelte2TsxComponentConstructorParameters<{ [x: string]: any; options: Options; value?: string | undefined; }>) => Select__SvelteComponent_' is not assignable to type 'new <Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any>(options: IComponentOptions<Props>) => SvelteComponentTyped<Props, Events, Slots>'.
          Types of parameters 'options' and 'options' are incompatible.
            Type 'IComponentOptions<Props>' is not assignable to type 'Svelte2TsxComponentConstructorParameters<{ [x: string]: any; options: Options; value?: string | undefined; }>'.
              Types of property 'props' are incompatible.
                Type 'Props | undefined' is not assignable to type '{ [x: string]: any; options: Options; value?: string | undefined; } | undefined'.
                  Type 'Props' is not assignable to type '{ [x: string]: any; options: Options; value?: string | undefined; } | undefined'.
                    Type 'Record<string, any>' is not assignable to type '{ [x: string]: any; options: Options; value?: string | undefined; }'.
                      Type 'Props' is not assignable to type '{ [x: string]: any; options: Options; value?: string | undefined; }'.
                        Property 'options' is missing in type 'Record<string, any>' but required in type '{ [x: string]: any; options: Options; value?: string | undefined; }'.
  Overload 2 of 3, '(component: typeof SvelteComponentTyped, componentOptions?: SvelteComponentOptions<any> | undefined, renderOptions?: RenderOptions<Queries> | undefined): RenderResult<...>', gave the following error.
    Argument of type 'typeof Select__SvelteComponent_' is not assignable to parameter of type 'typeof SvelteComponentTyped'.
  Overload 3 of 3, '(component: SvelteComponentTyped<{ form?: HTMLFormElement | null | undefined; id: string; value?: string | undefined; options: Options; }, any, any>, componentOptions?: SvelteComponentOptions<...> | undefined, renderOptions?: Omit<...> | undefined): RenderResult<...>', gave the following error.
    Argument of type 'typeof Select__SvelteComponent_' is not assignable to parameter of type 'SvelteComponentTyped<{ form?: HTMLFormElement | null | undefined; id: string; value?: string | undefined; options: Options; }, any, any>'.
      Type 'typeof Select__SvelteComponent_' is missing the following properties from type 'SvelteComponentTyped<{ form?: HTMLFormElement | null | undefined; id: string; value?: string | undefined; options: Options; }, any, any>': $set, $on, $destroy, $$prop_def, and 5 more.ts (2769)

Moreover, I'm not sure what the reasoning was in 167b46b, but switching back from SvelteComponentTyped to typeof SvelteComponent seems to appease TypeScript. Was there an opportunity to test these changes with ts-jest before this MR was merged? I'm just trying to discover where/when the type issues sneaked up on us.

@molily
Copy link

molily commented Jun 2, 2022

Probably related question, is this duplicate component definition on purpose? TypeScript (4.6) complains about it.

https://github.com/testing-library/svelte-testing-library/blob/main/types/index.d.ts#L26-L27

  component: SvelteComponent
  component: SvelteComponentTyped

Screenshot 2022-06-02 at 14 28 00

@ITenthusiasm
Copy link

ITenthusiasm commented Jun 2, 2022

@molily I could be wrong. But since it's a duplicate and since the type is unresolved, I'm assuming this is unintentional. It likely may have been a rebase or reverse merge artifact.

@yanick
Copy link
Collaborator

yanick commented Jun 2, 2022

Yeah, when I merged the PR it was pretty old, so I can see how it'd have merged more messily than expected. Ooops.

@yanick
Copy link
Collaborator

yanick commented Jun 2, 2022

I think I got it. Basically, render gets the classes directly, and not the instances, so everything has to be brought up one level up.

I have a potential fix at #195. Could I get some additional pairs of eyes to make sure I'm not utterly off my rockers?

@ITenthusiasm
Copy link

I'll try to give it a look within the next hour.

@akkumar
Copy link

akkumar commented Jun 4, 2022

Having a similar issue with typescript and svelte components.

Currently was having

"@testing-library/svelte": "3.1.2"

As per @theweekendgeek comments -

" saw that they were using svelte-testing-library 3.0.3 "

  • changing it ( rather, reverting it back ) to 3.0.3 seems to pass the tests involving svelte and ts components, for now.
        "@testing-library/svelte": "3.0.3",

FYI - for anyone wondering why their tests started failing in the render(SvelteComponent) method.

@sebastianrothe
Copy link
Collaborator

Having a similar issue with typescript and svelte components.

Currently was having

"@testing-library/svelte": "3.1.2"

As per @theweekendgeek comments -

" saw that they were using svelte-testing-library 3.0.3 "

* changing it ( rather, reverting  it back ) to 3.0.3 seems to pass the tests involving svelte and ts components, for now.
        "@testing-library/svelte": "3.0.3",

FYI - for anyone wondering why their tests started failing in the render(SvelteComponent) method.

3.1.1 is fine, too

@yanick
Copy link
Collaborator

yanick commented Jun 4, 2022

In the name of getting things unb0rked, I'll revert the type changes of 3.1.1, and set them back into a PR that can be tweaked and fixed at leisure.

@yanick
Copy link
Collaborator

yanick commented Jun 4, 2022

#198 it is.

@akkumar
Copy link

akkumar commented Jun 4, 2022

#198 it is.

Great. Can confirm that the jest unit tests for svelte components with typescript works with 3.1.3 indeed.

        "@testing-library/svelte": "3.1.3",

@bartektelec
Copy link

Can confirm rolling back to 3.1.3 fixed the issue for me as well

@mcous
Copy link
Collaborator

mcous commented Jan 29, 2024

@yanick with the latest versions of everything, I cannot reproduce this error on Svelte v3 nor Svelte v4. I think it can be closed and #298 will protect us from future regressions

@yanick yanick closed this as completed Jan 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

8 participants