Leff
Leff

Reputation: 1298

Typescript React type argument of type not assignable to parameter of type

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?

Upvotes: 2

Views: 895

Answers (1)

zhuber
zhuber

Reputation: 5524

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)}

Upvotes: 1

Related Questions