0

In my react application with typescript I am using semantic-ui-react for UI. this snabdobx shows the usage of Menu.Item in javascript but I wan to use it in typescript and got confused.

<Menu.Item  name="home"  active={activeItem === 'home'}
      onClick={this.handleItemClick}>

public handleItemClick = (
    e: React.MouseEvent<HTMLAnchorElement>,
    {name} // Here I ahve problem with typings to destruct the name
  ) => {
    this.setState({ activeItem: name });
  };

the types in the MenuItem.d.ts are

export interface MenuItemProps extends StrictMenuItemProps {[key: string]: any}

export interface StrictMenuItemProps {
  /*many other values */
  /** Internal name of the MenuItem. */
  name?: string

  onClick?: (event: React.MouseEvent<HTMLAnchorElement>, data: MenuItemProps) => void
}

here {name}:{name:string} does not work. and geting whole data the I can not setState with data.name

Amir-Mousavi
  • 4,273
  • 12
  • 70
  • 123

2 Answers2

2

typing like this means ({ name }) that argument name is any type, so it will not throw error.

to pass string e.g. "messages" to handleItemClick you should do something like this:

 handleItemClick = (name: string) => () => this.setState({ activeItem: name })
...
<Menu.Item
    name='messages'
    active={activeItem === 'messages'}
    onClick={this.handleItemClick('message')}
/>

As you can see in TS error message, second argument of Menu.click callback is MouseEvent not a {name: string}

btw: to be more type safe you can turn on strictFunctionTypes flag in compilerOptions in tsconfig.json file

---- Edited -----

I think i got your point. Please forgot previous part:

Menu.Item.onClick is already typed by @types lib in StrictMenuItemProps interface. To get onClick type you can use this syntax StrictMenuItemProps['onClick'] thats is equal to onClick?: (event: React.MouseEvent<HTMLAnchorElement>, data: MenuItemProps) => void but you can use it without copy code form lib.

So instead typing public handleItemClick by (arg1: Type1, arg2: Type2): Result { ... you can type it by public handleItemClick: StrictMenuItemProps['onClick'] = (e, {name}) => setState.

TS will match function's argument types to argument so e and name will not be any type

Example

Przemyslaw Jan Beigert
  • 2,351
  • 3
  • 14
  • 19
  • sorry, it is not what I am searching for, it is more like a hack. 1. why should I pass an string where it is already passed nested in data. 2.I was searching for the type of the name as getting destruct 3.it is not the approach which the official docs says – Amir-Mousavi Mar 06 '19 at 15:28
  • Also I think you did not read my comment reagarding the compiler error correctly that you have mentioned "`second argument of Menu.click callback is MouseEvent not a {name: string}` – Amir-Mousavi Mar 06 '19 at 15:29
  • I think i understand you now, please check edited part – Przemyslaw Jan Beigert Mar 06 '19 at 16:10
  • @Amir-Mousavi is this a solution that you're looking for? – Przemyslaw Jan Beigert Mar 12 '19 at 14:48
  • Actually before you send the edited version of the answer I figured it out and posted as answer, but your approach looks nice to yet had not time to test it and check if that is more beneficial or not but thanks for it, in few days got back to that project will test and accept your answer if it sounded more convenient – Amir-Mousavi Mar 12 '19 at 14:56
0

so it seems it does not matter that the name it self is of type string the whole object is of type MenuItemProps

therefore the following solved the issue

  public handleItemClick = (
    e: React.MouseEvent<HTMLAnchorElement>,
    { name }: MenuItemProps
  ) => {
    this.setState({ activeItem: name! });
  };
Amir-Mousavi
  • 4,273
  • 12
  • 70
  • 123