2

I have just started to work with Typescript in React apps. I am trying to implement simple toggle function using hooks in a component. I have defined useState like this:

const [menuList, setOpen] = React.useState<Array<keyof IOppmeldingModel>>([]); 

and a function to remove or add from the menuList:

function handleToggle(id:keyof IOppmeldingModel) {
        const menu = checkIfOpen(id);
        const updatedMenuList = menu ? menuList.concat(id) : menuList.filter(menuId => menuId !== id);
        setOpen(updatedMenuList);
    }

When I am trying to use this function like this:

 <Button
     ref={anchorRef}
     aria-controls="menu-list-grow"
     aria-haspopup="true"
     onClick={handleToggle(row.id)}
     variant="contained"
     size="small"
   >Velg
 </Button>

I get the error:

Argument of type 'number' is not assignable to parameter of type '"id" | "gjennomfortDato" | "gyldigTil" | "oppmeldtDatoTid" | "klasse" | "oppmeldtAv" | "menu"'.

The interface for IOppmeldingModel looks like this:

interface IOppmeldingModel {
    id: number,
    gjennomfortDato: string,
    gyldigTil: string,
    oppmeldtDatoTid: string,
    klasse: string,
    oppmeldtAv: string,
    menu: string,
}

Why am I getting this error, when I am sending a number, and a IOppmeldingModel can have number as a type for id property?

1 Answer 1

1

You are extracting property names of your IOppmeldingModel interface with keyof. That means that your id should be of type string and one of these values: '"id" | "gjennomfortDato" | "gyldigTil" | "oppmeldtDatoTid" | "klasse" | "oppmeldtAv" | "menu"'.

Instead of keyof, you can use

type OppmeldingType = string | number;

function handleToggle(id: OppmeldingType) {
    const menu = checkIfOpen(id);
    const updatedMenuList = menu ? menuList.concat(id) : menuList.filter(menuId => menuId !== id);
    setOpen(updatedMenuList);
}

Also be careful to call your toggle method only on click (not immediatelly)

onClick={() => handleToggle(row.id)}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.