Property 'updateEnabledSubmitSignup' does not exist on type 'typeof SvelteComponentDev' when trying to use an exported Svelte component function - jestjs

I want to export a function from a Svelte component and import it into a Jest test file for testing.
My expected result based on this post is that I can do:
// index.svelte
<script>
export function updateEnabledSubmitSignup(email, username, password, confirmedPassword) {
// ...
}
</script>
and then in my test file:
import Signup from "../src/routes/signup/index.svelte"
describe("signup page logic", () => {
test("ensure that the signup form button enablement conditions work properly", () => {
console.log(Signup, "5rm")
const failureOne = Signup.updateEnabledSubmitSignup()
expect(failureOne).toBe(false)
})
})
But running this code gives
tests/signup.test.ts:6:31 - error TS2339: Property 'updateEnabledSubmitSignup' does not exist on type 'typeof SvelteComponentDev'.
6 const failureOne = Signup.updateEnabledSubmitSignup()
It fails also if I do <script context="module"> with Property 'updateEnabledSubmitSignup' does not exist on type 'typeof SvelteComponentDev'.
If I try a named import like
import { updateEnabledSubmitSignup } from "../src/routes/signup/index.svelte"
then running the test gives error TS2614: Module '"*.svelte"' has no exported member 'updateEnabledSubmitSignup'. Did you mean to use 'import updateEnabledSubmitSignup from "*.svelte"' instead?
Anyone know how to do this please? This reddit post claims "You can use the tag at the top of your component to export a function." But even though I do that, the import fails.

Functions exported from the regular script are on the instance, e.g.
let signup;
onMount(() => signup.updateEnabledSubmitSignup());
<Signup bind:this={signup} />
Functions exported from the context=module script are named exports of the file.
If you get a type error from that, it is because your tooling did not determine the types correctly (it generically says *.svelte instead of the concrete type of this specific component). Question being, why your tests are doing type checking in the first place.

Related

how to remove Individual declarations in merged declaration must be all exported or all local.ts error?

I am implementing a redux store and I am pretty sure this is not a redux issue, in my store file, dog.store.ts I am exporting the store initial state:
export interface IDogState{
dog:number;
}
export const INITIAL_DOG_STATE:IDogState = {
dog:0
}
to later import it in my store.ts file:
import { IDogState,dogReducer,INITIAL_DOG_STATE } from "./redux/stores/dog.store";
this is where I get the error:
Individual declarations in merged declaration 'INITIAL_DOG_STATE' must
be all exported or all local.ts(2395)
Binding element 'INITIAL_DOG_STATE' implicitly has an 'any' type.
this was not an issue not long ago, I wonder if it is because a change in typescript or Angular compiler configuration.

Typescript - Dynamic class Type

I'm trying to build a sort of model Factory in Typescript.
I'm receiving a string parameter from an API call and I would like to istantiate a new object depending on the received value.
Here you can find a simple example of what I would like to accomplish:
/classes/ClassA.ts
export class ClassA {
doSomething() {
console.log("ClassA");
}
}
/classes/ClassB.ts
export class ClassB {
doSomething() {
console.log("ClassB");
}
}
/classes/index.ts
import { ClassA } from './ClassA';
import { ClassB } from './ClassB';
export { ClassA, ClassB }
Now, I would like to import all classes exported from index.ts (this file will be automatically updated when a new Class is being created) and run doSomething() on a class depending on a variable value:
/index.ts
import * as Classes from './classes';
const className: string = "ClassA";
new Classes[className]().doSomething()
In visualStudioCode I don't get any error, but at compile time I get:
error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof import("/testApp/src/tmp/classes/index")'.
Even changing className to "any" gives the same result.
If I remove className type
const className = "ClassA";
it works without any issue but I cannot proceed in this direction because received value is "typed" as string.
I know that prepending istantiation code with
// #ts-ignore
It works but I would like to avoid this kind of "tricks"
So, what would it be the correct way to type className getting it's possible values from the imported ts?
Thanks
Micko

Jest error with <Trans>: You forgot to export your component from the file it's defined in, or you might have mixed up default and named imports

Error: Uncaught [Error: Element type is invalid: expected a string
(for built-in components) or a class/function (for composite
components) but got: undefined. You likely forgot to export your
component from the file it's defined in, or you might have mixed up
default and named imports.
This is the error I was getting while running test in jest. React component which is being tested uses <Trans> from react-i18next. When I comment that portion of code, test were working as expected.
The error shown is very very very miss leading.
In my case it was missing mock for <Trans>. While I had mock for react-i18next, but since I had many components to cover with tests, and some of them were using <Trans> and some of them not, I copy/paste test files but totally forgot to check about mock. It took me few hours to notice it, after I replaced <Trans> to text like <Typography> from material-ui...
jest.mock('react-i18next', () => ({
withTranslation: () => (Component: any) => {
Component.defaultProps = {...Component.defaultProps, t: (children: any) => children};
return Component;
},
Trans: ({children}: any) => children, // this line was missing (() => jest.fn() might also work)
}));
Hope it will save some time for some of you :)
I faced the same issue, in order to resolve the issue I mocked the Trans component like this
jest.mock("react-i18next", () => ({
Trans: ({ i18nKey }: { i18nKey: string }) => i18nKey,
}));
Instead of passing the node, we can simply pass the i18nKey.
In my case, I am only checking the key value. Hope it helps!

Error:Element type is invalid: expected a string (for built-in components)or a class/function(for composite components)but got:object

import React from 'react'
const Newslist=(props)=>{
const Items = props.news.map((item)=>{
return (<h2>{item.title}</h2> )
});
return(<div> <Items/> </div>)
}
export default Newslist;
This piece of code is not displaying anything in the dom and showing the error
Error:Element type is invalid: expected a string (for built-in components)or a class/function(for composite components)but got:object
You're rendering Items as if it were a React component and not a JSX variable. As the error says, React components can only be created from strings (in the case of HTML elements), classes or functions. When you render something using the <JSX/> syntax it is passed as an argument to React.createElement. An array of JSX elements, which is what your map call returns, is not one of the accepted parameter types, so you are getting this error. I think this should work:
import React from 'react'
const Newslist=(props)=>{
const items = props.news.map((item)=>{
return (<h2>{item.title}</h2> )
});
return(<div> {items} </div>)
}
export default Newslist;

Exception with type definition for random-string module

I am trying to write a .d.ts for random-string.
I have this code:
declare module "random-string" {
export function randomString(opts?: Object): string;
}
I am able to import the module no problem then with:
import randomString = require('random-string');
and invoke:
console.log(randomString); // --> [Function: randomString]
However, this doesn't work with or without an argument:
console.log(randomString({length: 10});
console.log(randomString());
I get this error from tsc:
error TS2088: Cannot invoke an expression whose type lacks a call signature.
I looked in the source for random-string and found this code for the method I am trying to interface with:
module.exports = function randomString(opts) {
// Implementation...
};
I managed to write a .d.ts for the CSON module, no problem, but that was exporting a 'class' rather than a function directly. Is that significant?
Your declaration says there is a module named random-string with a function named randomString within it...
So your usage should be:
console.log(randomString.randomString({ length: 10 }));
console.log(randomString.randomString());
If the module does actually supply the function directly, you should adjust your definition to do the same:
declare module "random-string" {
function randomString(opts?: Object): string;
export = randomString;
}
This would allow you to call it as you do in your question.

Resources