24

I want to define the interface the proper way but I am having trouble because it is expecting an argument even though the argument is empty.

I am using useContext and I defined the interface like this:

    //react-auth0-spa.tsx
    interface Auth0Context {
        ......
        loginWithRedirect:  () => void; //I know this is the problem but I don't know what to define.
        ......
     }

in the provider, the value is :

 //react-auth0-spa.tsx
 <Auth0Context.Provider
     value=({
  ....
  loginWithRedirect: (...p: string[]) => auth0Client.loginWithRedirect(...p)
   ....
   })
>

now, I import the context to other the other file like so: const { isAuthenticated, loginWithRedirect, logout } = useAuth0()

and this is where the error occurs

///components/NavBar.tsx
const { isAuthenticated, loginWithRedirect, logout } = useAuth0()
<div>
      {!isAuthenticated && (
        <button onClick={() => loginWithRedirect({})}>Log in</button> //Expected 0 arguments, but got 1
      )}
</div>

so the problem is loginWithRedirect is expecting 1 argument, but () => loginWithRedirect({}) is an empty object. The problem can be solved by using any inside the interface but what should I put if I want to define it explicitly?

I tried loginWithRedirect: ({}) => void but now loginWithRedirect: (...p: string[]) => auth0Client.loginWithRedirect(...p) is giving me error like this Type '{}' is not assignable to type 'string'.ts(2322)

source code without typescript is https://github.com/auth0-samples/auth0-react-samples/tree/master/01-Login/src

Please help.

bradrar
  • 647
  • 1
  • 8
  • 19
  • Your question title and description are bit contradictory. Title says it's expecting 0 arguments means it's not expecting any argument at all. Description says it's expecting 1 argument. – Zain Ul Abideen Jun 02 '20 at 06:40
  • what is the type of the argument that `loginWithRedirect` can be called with ? – Ali Faris Jun 02 '20 at 06:44
  • Sorry if it's not clear. what I need is to change the interface `loginWithRedirect: () => void;` so that I can use ` – bradrar Jun 02 '20 at 07:21
  • @Ali I have used `loginWithRedirect: any; ` in the interface and it is working. The thing is, I need to explicitly define it. The problem I'm facing is, how can I define an argument in the interface if it's empty? ` – bradrar Jun 02 '20 at 07:23

2 Answers2

19

Problem in the first place is:

You provided signature of a function like this in the interface:

loginWithRedirect: () => void;

which means no argument and whenever you'll define that function you will obey this signature but in contrary you are passing argument to the function while giving it's definition.

Solution

Why not doing like this?

//react-auth0-spa.tsx
    interface Auth0Context {
        ......
        loginWithRedirect:  (p: object) => void;
        ......
     }
Zain Ul Abideen
  • 1,617
  • 1
  • 11
  • 25
  • Yes, I provided it like this `loginWithRedirect: () => void;` but what I need to do is change the interface so it will accept `onClick={() => loginWithRedirect({})}` . That way, I will have 1 argument to satisfy typescript – bradrar Jun 02 '20 at 07:19
  • @bradrar but that one argument's type must be match with the argument's type in signature of the function. – Zain Ul Abideen Jun 02 '20 at 07:21
  • Yes, But I don't know how. I have read the docs https://www.typescriptlang.org/docs/handbook/functions.html about functions but the examples here have parameters, in my case, the function is empty. – bradrar Jun 02 '20 at 07:25
  • Thanks for the answer,I tried it and now `onClick={() => loginWithRedirect({})}` error is `Argument of type '{}' is not assignable to parameter of type 'string[]'. Type '{}' is missing the following properties from type 'string[]': length, pop, push, concat, and 28 more.ts(2345)` – bradrar Jun 02 '20 at 07:45
  • 1
    @bradrar I've updated the answer, can you give it a try – Zain Ul Abideen Jun 02 '20 at 07:50
  • Thank you! your previous answer gave me a clue! So what I did is `loginWithRedirect: ({}:object) => void;` it is now working properly. Your answer is working as well. Thank you very much – bradrar Jun 02 '20 at 07:55
0

The mistake I was doing is didn't mention the parameter type, like undernetah

interface Props {
  openSnackbarHandler: () => void
}
export const app:React.FC<Props> = ({ openSnackbarHandler }) => {

   openSnackbarHandler("Password has been changed successfully!")

}

// method passed as props
const openSnackbarHandler: (mesg: string) => {
         console.log(mesg);
}

just define the type in parameter:

interface Props {
  openSnackbarHandler: (mesg: string) => void
}
Ericgit
  • 6,089
  • 2
  • 42
  • 53